Boost logo

Boost :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2008-02-04 08:32:13


Robert Ramey ha escrito:

> "JOAQUIN LOPEZ MU?Z" wrote:
> > Hello Robert,
> >
> > ----- Mensaje original -----
> > De: Robert Ramey <ramey_at_[hidden]>
> > Fecha: Domingo, Febrero 3, 2008 8:01 pm
> > Asunto: [boost] question about flyweight
> > Para: boost_at_[hidden]

[...]

> >> b) I'm curious about the serialization implementation. Why didn't
> >> you choose just to serialize the factory? This seems to me the most
> >> obvious implementation and I wonder why you didn't feel it was
> >> a good choice.
> > [...]
> >> In short, I don't see why a "helper" is required.
> >
> > Details aside, it all boils down to this:
> >
> > ar << f.h;
> >
> > This only works off the shelf if f.h is a pointer, which is not
> > the case in general (the type of this handle is provided
> > by the particular factory used, and need not be a pointer,
> > for instance in set_factroy is a std::set::iterator).
> > Briefly put, the serialization helper used by flyweight mimics
> > for handle_type the tracking facilities Boost.Serialization
> > provides natively for pointers.
>
> The default is to track if and only if its serialized through a pointer.
>
> If the tracking level serialization trait for flyweight<T> is set to
> track_always it should work
> with all objects.
>
> I would think that you could get the effect you intend by just setting
> this serialization trait.for these types.

I can do something of sorts, but it's not as efficient as with the aid of a
helper: Suppose T is tracked, then your proposed approach would be
something like this:

  template<
    class Archive,
    typename T,typename Arg1,typename Arg2,typename Arg3
>
  void save(
    Archive& ar,const ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3>& f,
    const unsigned int version)
  {
      typedef ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3> flyweight;
      ar << &f.get();
  }

  template<
    class Archive,
    typename T,typename Arg1,typename Arg2,typename Arg3
>
  void load(
    Archive& ar,const ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3>& f,
    const unsigned int version)
  {
    typedef ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3> flyweight;
    T* p;
    ar >> p;
    f=*p; // HERE
    if(&f.get()!=p){
      ar.reset_object_address(&f.get(),p);
      delete p;
    }
  }

The problem is with the line marked //HERE : we are incurring a lookup
operation for each duplicate flyweight, while this is avoided when a helper is
used. As a matter of fact, I measured this approach against the helper
implementation and the performance of the latter is easily 2x or 3x better
(I don't remember the exact figures, I can retest if you're interested.)

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk