Bad news from the Ivory Tower, part III.

------------------------------- snip -------------------------------
#!/bin/bash

n=100      # number of classes 
m=10000000 # number of cycles
cc=/usr/bin/g++

function useit() {
        time for i in $s ; do $cc -c $i.cpp ; done 
        echo ".cpp: `cat *.cpp | wc -c`"
        echo ".o: `cat *.o | wc -c`"
        echo "
        #include \"1.h\"
        int main() {
                int s = 0;
                X1 x;
                for (int i = $m; --i >= 0;)
                        s += x.clone()->x();
                return s;
        }
        " > main.cpp
        $cc -c -O3 main.cpp
        $cc main.o 1.o
        time ./a.out
        echo
}

s=`seq 1 $n`;

rm -rf 1 2
mkdir 1 2
cd 1
echo "struct X { virtual X * clone()=0; virtual int x()=0; };" > 0.h
for i in $s ; do
        echo "#include \"0.h\"" > $i.h
        echo "struct X$i : X { virtual X * clone(); int x() {return $i;} }; " 
>> $i.h
        echo "#include \"$i.h\"" > $i.cpp
        echo "X * X$i::clone() { return new X$i; }" >> $i.cpp
done

echo
echo "Bald pointers:"
useit

cd ../2
echo "#include <memory>" > 0.h
echo "struct X { virtual std::auto_ptr<X> clone()=0; virtual int x()=0;};" >> 
0.h
for i in $s ; do
        echo "#include \"0.h\"" > $i.h
        echo "struct X$i : X { virtual std::auto_ptr<X> clone(); int x() 
{return $i; }}; " >> $i.h
        echo "#include \"$i.h\"" > $i.cpp
        echo "std::auto_ptr<X> X$i::clone() { return std::auto_ptr<X>(new X$i); 
}" >> $i.cpp
done

echo
echo "std::auto_ptr<>:"
useit
------------------------------- snip -------------------------------

[EMAIL PROTECTED]:/tmp/t1 > ./1.sh 

Bald pointers:

real    0m2.998s
user    0m2.224s
sys     0m0.764s
.cpp: 5276
.o: 312308

real    0m1.342s
user    0m1.152s
sys     0m0.184s


std::auto_ptr<>:

real    0m15.354s
user    0m13.461s
sys     0m1.784s
.cpp: 8376
.o: 476308

real    0m1.807s
user    0m1.792s
sys     0m0.012s

------------------------------- snip -------------------------------

Summary: Using std::auto_ptr<X> instead of X* for cloning costs us

  - a factor 5(!) in compile time
  - a factor 1.3(!) in run time
  [- a factor 1.5 in .cpp size]
  [- a factor 1.5 in .o size]

For no good reason. Both (yes there are two!) places where we call
clone() look like 

        it->inset = it->inset->clone().release();

So it's not much clarity we gain by using std::auto_ptr<> at all.

Andre'

Reply via email to