Code Comments
Programming Forum and web based access to our favorite programming groups.* Sam: > Yannick Tremblay writes: > > > The entire design is completely braindead. A separate object, a tiny > object that holds the reference count, gets instantiated for every > object tracked by shared_ptr. This is insane. Heavy use of shared_ptr is > just going to hammer your heap like there's no tomorrow. This is > horrible design. The correct approach is to store the reference count in > superclass and derive from it. You can't then attach shared_ptr to an > arbitrary libstdc++ object, of course, so you just multiply-inherit from > it. How hard is that? > > Then you have the shared_ptr itself, an object that holds two pointers, > one to the original object, the other to the reference count. > > Which means that most compilers won't be able to hold a shared_ptr in > CPU registers, like ordinary pointers. Instead, things are going to get > tossed around in memory. > > There are also several other design flaws as well. Like the fact that > each time a reference count gets updated, it involves a call to a > library function. Reference count increment/decrement cannot be inlined, > due to a real first class fookup in the templates. After I read through > the class definition, I just shook my head, laughed, then quickly coded > my own reference-counted object implementation, and ended up > benchmarking it 15% faster than Boost's disgusting implementation. Have you looketh at boost::intrusive_ptr? Cheers, - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail?
Post Follow-up to this messageOn Mar 27, 12:13 pm, Sam <s...@email-scan.com> wrote: > Yannick Tremblay writes: > Like the rest of Boost's code? That's not my experience. > > > > > The entire design is completely braindead. A separate object, a tiny > object that holds the reference count, gets instantiated for every object > tracked by shared_ptr. This is insane. Heavy use of shared_ptr is just goi ng > to hammer your heap like there's no tomorrow. Use a custom allocator. Or use a platform with a better default allocator. Also the draft standard (and I think the next boost release) has make_shared or something like that that will encapsulate 'new' and will allocate the reference count and your object with a single allocation; as a plus it will be binary compatible with the default separate referece counted shared_ptrs. > This is horrible design. The > correct approach is to store the reference count in superclass and derive > from it. You can't then attach shared_ptr to an arbitrary libstdc++ object , > of course, so you just multiply-inherit from it. How hard is that? > If you do not want to pay for a separate heap allocated reference count, use boost::intrusive_ptr. Which doesn't force you to derive from some superclass. Not requiring changes in user classes is good desing, not horrible design. Also note that using a separate reference count gives you weak_ptr (technically you can have it with an intrusive reference counted smart pointer, but you would have to defer deallocation of the pointed object untill the last weak pointer dies, which is Not What You Want (TM) ). > Then you have the shared_ptr itself, an object that holds two pointers, on e > to the original object, the other to the reference count. > > Which means that most compilers won't be able to hold a shared_ptr in CPU > registers, like ordinary pointers. Most compilers? Maybe from the last century. I would be surprised if any half-recent compiler did that. > Instead, things are going to get tossed > around in memory. > > There are also several other design flaws as well. Like the fact that each > time a reference count gets updated, it involves a call to a library > function. On most plattforms boost shared_ptr uses inline asm or compiler intrinsics for reference count updates. Calls to platfrom specific mutex lock/unlock are only a fall back. And you know that, as you said the same thing in the previous paragraph. Also I would like to know how it "gets it partially wrong". > Reference count increment/decrement cannot be inlined, due to a > real first class fookup in the templates. What is that supposed to mean? > After I read through the class > definition, I just shook my head, laughed, then quickly coded my own > reference-counted object implementation, and ended up benchmarking it 15% > faster than Boost's disgusting implementation. > 15% is hardly impressive. It is unlikely that shared_ptr operations are responsible of more than 1% of your application run time (if they are, you are likely doing something wrong). Improving 15% on that isn't a great accomplishment nor a good use of your time. With a custom tailored shared ptr you can do much, much better (as, I'm sure, Chris Thomasson is going to tell you ;) ). But of course you lose most of the nice properties of shared_ptr: weak_ptr, support for incomplete types, custom deleter, aliasing constructor etc, etc... and of course a peer reviewed, widely tested design (even blessed by the standard committee). > > Yes. No. -- gpd
Post Follow-up to this messagegpderetta wrote: > > 15% is hardly impressive. It is unlikely that shared_ptr operations > are responsible of more than 1% of your application run time (if they > are, you are likely doing something wrong). Improving 15% on that > isn't a great accomplishment nor a good use of your time. I once made a comparison of boost::shared_ptr and loki::SmartPtr, which uses a custom allocator (both with non-intrusive reference counting). In debug mode, loki was slightly slower because of massive policy templates, but when compiled with -O2 it needed only 50% of the time of boost::shared_ptr. Of course, their design is rather complementary. Boost::shared_ptr is a more general and broad approach, while Loki provides possibilities to configure every tiny bit with policies. Each has it's strength and weaknesses. I have used both and didn't run into problems so far. lg, Michael
Post Follow-up to this message> This just means, that you are making a copy of an object where the > destructor is in progress. That's simply a bug and should be avoided ;-) > > best regards, > Torsten I agree. I would put it simply -- you cannot call 'AddRef' unless you have an explicit or implicit reference to an object. The 'AddRef' function is not special, it must be called with a reference just like every other function. The puzzle is this -- how did you get a pointer to object to call 'AddRef' on anyway? I've heard a lot of talk about strong thread safety and the like, but I have to admit, I don't get it. In order to call 'AddRef' on an object, you need a pointer to it, and how could you possibly have gotten that pointer without something that already had a reference? The existence of a pointer should mean the existence of a reference -- otherwise how can you know that pointer remains valid, whether a call for AddRef or for any other purpose? DS
Post Follow-up to this messageOn Mar 27, 8:12=A0am, gpderetta <gpdere...@gmail.com> wrote: > On Mar 27, 12:13 pm, Sam <s...@email-scan.com> wrote: > > sign ted > > Like the rest ofBoost'scode? That's not my experience. I think some Boost libraries are better than others though. http://www.webEbenezer.net/comparison.html Brian
Post Follow-up to this messageDavid Schwartz wrote: > > > I agree. I would put it simply -- you cannot call 'AddRef' unless you > have an explicit or implicit reference to an object. The 'AddRef' > function is not special, it must be called with a reference just like > every other function. > > The puzzle is this -- how did you get a pointer to object to call > 'AddRef' on anyway? > > I've heard a lot of talk about strong thread safety and the like, but > I have to admit, I don't get it. In order to call 'AddRef' on an > object, you need a pointer to it, and how could you possibly have > gotten that pointer without something that already had a reference? > > The existence of a pointer should mean the existence of a reference -- > otherwise how can you know that pointer remains valid, whether a call > for AddRef or for any other purpose? See http://www.open-std.org/JTC1/SC22/W...297.html#atomic regards, alexander.
Post Follow-up to this messageOn Mar 27, 9:42 pm, c...@mailvault.com wrote: > On Mar 27, 8:12 am, gpderetta <gpdere...@gmail.com> wrote: > > > > > > I think some Boost libraries are better than others though.http://www.webEbeneze r.net/comparison.html > Use an std::vector (or boost::array) instead of std::deque or std::list for applications where serialization performance is critical. -- gpd
Post Follow-up to this messageOn Mar 27, 1:26 pm, David Schwartz <dav...@webmaster.com> wrote: > > > I agree. I would put it simply -- you cannot call 'AddRef' unless you > have an explicit or implicit reference to an object. The 'AddRef' > function is not special, it must be called with a reference just like > every other function. > > The puzzle is this -- how did you get a pointer to object to call > 'AddRef' on anyway? > > I've heard a lot of talk about strong thread safety and the like, but > I have to admit, I don't get it. In order to call 'AddRef' on an > object, you need a pointer to it, and how could you possibly have > gotten that pointer without something that already had a reference? > > The existence of a pointer should mean the existence of a reference -- > otherwise how can you know that pointer remains valid, whether a call > for AddRef or for any other purpose? > > DS The owner calls AddRef before it hands you a pointer.
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.