Boost logo

Boost :

Subject: Re: [boost] [Block Pointer] Update
From: Phil Bouchard (philippeb8_at_[hidden])
Date: 2016-03-10 19:47:11


On 03/09/2016 11:28 PM, Phil Bouchard wrote:
> Hi,
>
> - So I've restructured all the code in the correct namespaces
> boost::smart_ptr & boost::smart_ptr::detail:
> https://github.com/philippeb8/block_ptr/tree/master/include/boost/smart_ptr
>
>
> - I am now using another smart pointer to refer to proxies because it is
> safer but the code is 15% slower than without it (now ~= shared_ptr<>):
>
> make:
> auto_ptr: 26211292 ns
> shared_ptr: 27291607 ns
> block_ptr: 61097868 ns
>
> new:
> auto_ptr: 23240569 ns
> shared_ptr: 48016207 ns
> block_ptr: 55554121 ns

Note that it is possible & easy to use the fast_pool_allocator to
allocate objects just by using the following line in benchmark.cpp:

worker_new< boost::block_ptr<int>, fastblock<int> >();

Or:
https://github.com/philippeb8/block_ptr/blob/master/example/benchmark.cpp#L99

And this way block_ptr<> will be 5% faster than shared_ptr<>:

make:
auto_ptr: 25673501 ns
shared_ptr: 26853061 ns
block_ptr: 61874962 ns

new:
auto_ptr: 22326728 ns
shared_ptr: 47143526 ns
block_ptr: 45007803 ns

This is an unfair comparison but my point is using this fast allocator
can be done easily.

> - Because of the removal of the proxy optimization there is a new
> caveat; if you assign an rvalue (temporary pointer on the stack) to a
> pointer on the heap (opposite of normal heap object assigned to stack
> pointer) then there the behavior will be undefined. I am looking to fix
> it or throw an exception but for now it's better not to use rvalues when
> assigning to pointer living on the heap as such:
> https://github.com/philippeb8/block_ptr/blob/master/example/t100_test1.cpp#L32

I fixed the problem and now the correct way to use the pointer is by
passing around a proxy explicitly:

[...]
block_ptr<neuron_sight> t100 = new block<neuron_sight>("I eat ([a-z]+)
then drink ([a-z]+)");
t100->sub_[0].second = block_ptr<neuron_sight>(t100.proxy(), new
block<neuron_sight>("beef|chicken"));
t100->sub_[1].second = block_ptr<neuron_sight>(t100.proxy(), new
block<neuron_sight>("vodka|water"));

Or:
https://github.com/philippeb8/block_ptr/blob/master/example/t100_test1.cpp#L31

I will fix make_block<>() to follow this syntax but this is how things
should be done. Another useful example is by defining the internals of
a container:

struct list {
public:
     list() {}
     void clear() {
         root.reset();
     }
     void insert() {
         if(root.get() == 0) {
             root = new block<node>();
         } else {
             root->next = block_ptr<node>(root.proxy(), new
block<node>()); //<- Correct way
             root->next->prior = root;
             root = root->next;
         }
     }
     ~list()
     {
     }
private:
     block_ptr<node> root;
};

Or:
https://github.com/philippeb8/block_ptr/blob/master/example/block_ptr_test2.cpp#L44

The explicit proxy states where a set of allocations should be defined
as unique. That set can be merged with another set.

Regards,
-Phil


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