== 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.
