On 03/13/2016 12:00 AM, Glen Fernandes wrote:
On Sat, Mar 12, 2016 at 10:12 PM, Phil Bouchard wrote:
On 03/12/2016 09:22 PM, Glen Fernandes wrote:
To add to our earlier discussion, you should also include the benchmark for allocate_shared() with fast_pool_allocator.
Good point, I was not aware it could be used this way. I just added fast_pool_allocator<>() to the benchmark so now the comparison is fair and block_ptr<> still is faster by 125%:
Hi Phil,
The other thing I observed in your benchmarks is the distinction between 'new T' and 'new T()'. i.e. make_shared() and allocate_shared() (and make_unique() too) all value-initialize. 'new T' (and T is 'int' in your example) is default-initialization (while 'new T()' would be value-initialization).
You can use boost::make_shared_noinit() and boost::allocate_shared_noinit() (and boost::make_unique_noinit() also) if you want default-initialization. Or you can use 'new T()' instead of 'new T' and have value-initialization.
There is not much difference, now block_ptr<> is still 132% faster than shared_ptr<>: make: auto_ptr: 25564043 ns shared_ptr: 26421429 ns make alloc: shared_ptr: 11725542 ns make alloc noinit: shared_ptr: 11665724 ns <- new: auto_ptr: 23546857 ns shared_ptr: 49000954 ns block_ptr: 8791379 ns <-
(I haven't looked at the implementation of block_ptr yet, or the design, or the purpose of it, I just saw the thread on benchmarks and examined your benchmark program source).
I keep cleaning up the code and now I think it is very easy to understand: proxy_ptr<node> x; block_ptr<node> v = block_ptr<node>(x, new block<node>(x)); v->next = v; You have 2 types of pointers: proxy_ptr<> and block_ptr<>. proxy_ptr<> is the root of the tree block_ptr<> will build on. When proxy_ptr<> gets deleted then all block_ptr<> associated to it will be wiped out as well. The purpose of block_ptr<> is to delete cyclic pointers.