From: Thorsten Ottosen (nesotto_at_[hidden])
Date: 2004-10-08 13:11:28


"Jonathan Turkanis" <technews_at_[hidden]> wrote in message
news:cjvg1n$r8s$1_at_sea.gmane.org...
|
| "Thorsten Ottosen" <nesotto_at_[hidden]> wrote in message
| news:cjvavc$hot$1_at_sea.gmane.org...
| > Hi Jonathan,
|
| > | 4. Since performance is one of the main design goals, I'm suprised that
| > | attempting to insert a null pointer causes an exception rather than an
| > insertion
| > | failure. The same goes for invoking the functions for back, front,
pop_back
| > and
| > | pop_front with an empty container. By coincidence, this morning I was
| > | experimenting with some code that invokes a function pointer with a
pointer
| > as
| > | argument, like so
| > |
| > | f_(p_)
| > |
| > | in an inner loop. I tried replacing the above code with
| > |
| > | if (p_)
| > | f_(p_);
| > | else
| > | throw std::runtime_error(...);
| > |
| > | I found an enormous slowdown, which should be no surprise.
| >
| > yeah, I dunno, this might depend heavily on the compiler. what compiler do
you
| > use?
|
| Good point. I was using VC7.1. I ran the same test with como4.3.3/VC7.1
Intel
| 8.0 for windows and GCC 3.4.3 (Cygwin) and didn't see a significant
difference.
| But the fact that it makes a difference for some compilers, esp. a widely
used
| one, should be significant.

There is one thing we often overlook when we want to place 0 into a large
container: we must check every
indexing for not being zero and that might counter-balance the effect of
putting 0 in there in the first place.

I did some testing with a handy null_object helper class that avoids all
allocation overhead of null-objects.
( used like null_animal : public boost::null_object<animal,null_animal> {
.. }; )

Then I compared code like

for_each(.ptr_container_with_null_objects )
{
     i->foo(); // non-virtual
     i->bar(); // virtual
}

with

for_each( standard_container_with_0s )
{
    if( *i )
   {
     (*i)->foo(); // non-virtual
     (*i)->bar(); // virtual
   }
}

on vc7.1

In this setting a if the we have 2 : 5 nulls (2 nulls, 3 normal), checking for
0 wins. If we have 1 : 5 nulls or better
the null object method wins. Basically I would guess this ratio depends
entirely on how many if() we can execute for each virtual function
dispatch since the body of null-object function is always trivial.

Conclusion: disallowing 0 will not only lead to simpler, safer programs, but
it will probably also boost performance.

br

Thorsten