Struct/Class member/function pointer/ref Comparing

Wyverex wyverex.cypher at gmail.com
Tue Aug 12 15:11:09 PDT 2008


Was writing some time critical code, and as I added new objects to the 
thing I got a large slow down... dope to many classes!  so I converted 
what I could to structs and everything ran at a good speed.  So I 
started to think is it faster to use member functions or external 
functions on a struct.  Also began thinking about references verse 
pointers.  So I wrote a program in the hopes of timing it.


http://wastelandstudio.hopto.org/img/DTime1Chart.jpg
http://wastelandstudio.hopto.org/img/DTime1Graph.jpg

Its clear to see the a struct member function and a function that takes 
a structure pointer performs the best. Also we see with full 
optimization a function that takes a struct pointer performed the best.
References were mostly slower then pointer.  I though there had been 
talks about making the following legal in D2..

Class A { .... /* no func! */ }
void func( A a, ...) { .... }
A.func(...) { ... }

If this would work with class pointers it would make friend functions
that look like member functions faster then public member functions, or 
even same function with a reference...


Also is a put on the stack??
void func( in A* a, ... ) //copy of address

what about?
void func( ref A* a, ... ) //reference to pointer

compared to
void func( A** a, ... ) //copy of pointers address

is there a performance hit somewhere in there?





Source:  test.d

module test;

import
   tango.io.Stdout,
   Float = tango.text.convert.Float,
   tango.time.StopWatch;

bool dummy() { scope bool ret; return !ret; }

struct S1
{
   uint a,b,c,d;

   void func() { a = 1; b = 2; if(dummy) c = 3; d = 4; }
}

struct S2
{
   uint a,b,c,d;
}
void func( S2* s) { s.a = 1; s.b = 2; if(dummy) s.c = 3; s.d = 4; }
void funcRef( ref S2 s) { s.a = 1; s.b = 2; if(dummy) s.c = 3; s.d = 4; }

class C1
{
   uint a,b,c,d;
   void func() { a = 1; b = 2; if(dummy) c = 3; d = 4; }
}

class C2
{
   uint a,b,c,d;
}
void func( C2* s) { s.a = 1; s.b = 2; if(dummy) s.c = 3; s.d = 4; }
void funcRef( ref C2 s) { s.a = 1; s.b = 2; if(dummy) s.c = 3; s.d = 4; }


const uint size = 10_000;
const double iter = 100_000.0;

void main()
{
   S1[size] s1;
   S2[size] s2;
   C1[size] c1; foreach( ref c; c1 ) c = new C1;
   C2[size] c2; foreach( ref c; c2 ) c = new C2;

   StopWatch timer;
   double a1 = 0.0, a2 = 0.0, a3 = 0.0, a4 = 0.0, a5 =0.0, a6 = 0.0, i;

   for(i = 0.0; i < iter; i+=1.0)
   {

   timer.start;
   foreach( ref s; s1 )
     s.func;
   a1 += timer.stop;

   timer.start;
   foreach( ref s; s2 )
     func(&s);
   a2 += timer.stop;

   timer.start;
   foreach( ref s; c1 )
     s.func;
   a3 += timer.stop;

   timer.start;
   foreach( ref s; c2 )
     func(&s);
   a4 += timer.stop;

   timer.start;
   foreach( ref s; s2 )
     funcRef(s);
   a5 += timer.stop;

   timer.start;
   foreach( ref s; c2 )
     funcRef(s);
   a6 += timer.stop;


   }

   version(excel)
   {  // print line so I can copy into excel
   Stdout(Float.toString(a1, 4))('\t')(Float.toString(a2, 4))('\t')
   (Float.toString(a5, 4))('\t')(Float.toString(a3, 4))('\t')
   (Float.toString(a4, 4))('\t')(Float.toString(a6, 4))('\t').newline;

   }else{
   Stdout("Function in Struct:")(Float.toString(a1, 4)).newline;
   Stdout("Function Struct Pointer:")(Float.toString(a2, 4)).newline;
   Stdout("Function Struct Ref:")(Float.toString(a5, 4)).newline;

   Stdout("Function in Class:")(Float.toString(a3, 4)).newline;
   Stdout("Function Class Pointer:")(Float.toString(a4, 4)).newline;
   Stdout("Function Class Ref:")(Float.toString(a6, 4)).newline;
   }

}



More information about the Digitalmars-d mailing list