My biggest concern with this model is that access to the public Cache
object from other public objects results in additional allocations of a
Cache value. Think about when we are inside a Serializable object and we
access the Cache from DataOutput.

As value:
Serializable* MyClass::fromData(DataInput& dataInput) {
  auto cache = dataOutput.getCache();
  ...
}
In this the value of cache will RVO the allocation of Cache in the getCache
call into the stack of this method, great. The problem is that Cache must
contain a std::shared_ptr<CacheImpl> which means that each allocation is 8
bytes (pointer to control block and pointer to CacheImpl) as well as having
to increment the strong counter in the control block. On exit/descope, the
Cache will have to decrement the control block as well.

Using current shared_ptr pimple model:
Serializable* MyClass::fromData(DataInput& dataInput) {
  auto& cache = dataOutput.getCache();
  ...
}
We only suffer the ref allocation of 4 bytes and no ref count. Since this
function call can't survive past the lifespan of Cache/CacheImpl they don't
need to have shared_ptr and refcounting.

Given that this method could be called numerous times is the overhead of
the value version going to be a significant performance issue?

I worry that moves and RVO is just beyond most developers. Heck I didn't
know anything about it until we started exploring it.



-Jake


On Tue, Sep 12, 2017 at 8:06 AM David Kimura <dkim...@pivotal.io> wrote:

> Follow up of attached discussion after more investigation.  I created an
> example of returning Cache as shared pointer versus raw value:
>
>     https://github.com/dgkimura/geode-native-sandbox
>
> I still like returning by value as it lets the user do what they want with
> their object.
>
>     // Here user creates object on their stack.
>     auto c = CacheFactory::createFactory().create();
>
>     // Here user creates smart pointer in their heap.
>     auto cptr =
> std::make_shared<Cache>(CacheFactory::createFactory().create());
>
> Difficulty of implementing this is high due to circular dependencies of
> Cache/CacheImpl as well as objects hanging off CacheImpl that return
> Cache.  We must be extra careful when dealing with move/copy semantics of
> Cache/CacheImpl.
>
> Alternative, is to keep as is and only permit heap allocations from
> factory using shared pointers.
>
> Thanks,
> David
>

Reply via email to