== Quote from Andrei Alexandrescu ([email protected])'s article
> Steven Schveighoffer wrote:
> > A delegate is equivalent to a struct member function call.  (load data
> > pointer (i.e. this), push args, call function)
> I think this particular point is incorrect.
> Andrei

Most of the overhead from indirect function calls come from the fact that they
(usually) can't be inlined, not because they are indirect.  The struct member
function call is faster mostly because it can be inlined, not because it's 
direct.

Here's roughly what the ASM would look like for a call to a member function of a
struct on the stack, if I is a metasyntactic variable for any immediate value:

mov EAX, EBP;  // Copy frame pointer to EAX
add EAX, I;    // Add the offset of the struct to EAX.
push EAX;      // EAX is now the this ptr.  Push it.
call I;        // Call the function.

And for a delegate that lives on the stack:

mov EAX, [EBP + I];  // Move delegate's this ptr into EAX.
push EAX;            // Push delegate's this ptr onto stack.
call [EBP + I];      // Call whatever address is at offset I from EBP.

I've actually benchmarked how much indirect function calls cost compared to 
direct
calls that aren't inlined.  The short answer is it's not measurable, at least 
when
calling the same function indirectly in a loop over and over.  It could in 
theory
cause pipeline stalls because it's a branch, but according to some Intel
optimization manual Don posted here a while back, modern CPUs predict the 
address
of indirect function calls in their branch predictor.  This means that if the 
same
path is taken again and again, the overhead will be negligible.

Reply via email to