bs@alice.UucP (Bjarne Stroustrup) (10/16/86)
/*
here are some more timings showing function call costs:
*/
struct s {
int a;
virtual f1(); // virtual function
f3() { a++; return a; } // calls will be inlined
f4(); // member function
};
s::f1() { a++; return a;}
s::f4() { a++; return a;}
f2(s* p) {p->a++; return p->a; } // ``normal'' function
f5(register s* p) {p->a++; return p->a; } // register argument
int (*pf)(s*) = &f2;
main() {
s a;
register s* p = &a;
// for (register int i = 100000; 0<i; i--) p->f1();
// for (register int i = 100000; 0<i; i--) f2(p);
// for (register int i = 100000; 0<i; i--) p->f3();
// for (register int i = 100000; 0<i; i--) ;
// for (register int i = 100000; 0<i; i--) p->f4();
// for (register int i = 100000; 0<i; i--) (*pf)(p);
for (register int i = 100000; 0<i; i--) f5(p);
}
/*
Times in seconds, that is, the time needed per iteration in microseconds:
virtual member empty
fct fct inline fct loop
p->f1() f2(p) p->f3() p->f4() pf(p) f5(p) ;
VAX11/750: 41 32 5 41 31 40 3
VAX11/785: 21 15 2 20 16 20 1
sun3: 8 6 1 8 7 7 1
AT&T 3B20: 20 16 4 18 18 18 2
Amdahl5860: 1.1 1.0 .2 1.0 1.1 1.0 .2
AT&T6300+ (s) 30 26 12 28 28 27 10
AT&T6300+ (l) 46 42 20 42 42 41 10
A 6300+ is an AT clone (small and large models used for pointers, long i).
Release 1.1 was used except for the 6300+. There I used a toy.
So
(1) A virtual member call is as fast as a non-virtual member call.
(2) A member call is as fast as an equivalent non-member call.
(3) Inlining function calls can be very effective in speeding up code.
(4) Declaring "this" a register argument in a function with only little
use of "this" (as in the examples above) is a loss.
(5) VAX function calls are relatively expensive (not news).
Thanks to all who help time the examples.
*/