I think this is a rather interesting question, and I saw a lot of assumptions about what the compiler can do, but I wanted to take a closer look and find out for sure. So I took the e.James program and ran it through GCC to get the build. I must say that I really do not know the meeting, so someone will correct me if I am wrong, but I think we can reasonably conclude what is happening. :)
Compilation with -O0 (no optimization)
For Foo1 we see that the array offset is calculated before each function call:
movl 8(%ebp), %eax movl (%eax), %edx movl -4(%ebp), %eax leal (%edx,%eax), %eax movl %eax, (%esp) call __ZN10SomeObject10Operation1Ev
This is for all six method calls, simply using different method names. Foo2 has a bit of setup code to get the link
movl 8(%ebp), %eax movl (%eax), %edx movl -4(%ebp), %eax leal (%edx,%eax), %eax movl %eax, -8(%ebp)
And then six of them that look like a push pointer to the stack and a function call:
movl -8(%ebp), %eax movl %eax, (%esp) call __ZN10SomeObject10Operation1Ev
Pretty much what we would expect without optimization. The output was
Foo1: 18472 Foo2: 17684
Compilation with -O1 (minimal optimization)
Foo1 bit more efficient, but still resets the array offset every time:
movl %esi, %eax addl (%ebx), %eax movl %eax, (%esp) call __ZN10SomeObject10Operation1Ev
Foo2 looks, saves the value of ebx ( addl (%edi), %ebx ), and then makes the following calls:
movl %ebx, (%esp) call __ZN10SomeObject10Operation1Ev
Were at times
Foo1: 4979 Foo2: 4977
Compilation with -O2 (moderate optimization)
When compiling with -O2 GCC just got rid of all this, and every call to Foo1 or Foo2 just added 594 to dummy (99 increments * 6 calls = 594 increments):
imull $594, %eax, %eax addl %eax, _dummy
There were no calls to the methods of the object, although these methods remained in the code. As expected, times were here
Foo1: 1 Foo2: 0
I think this tells us that Foo2 works a little faster without optimization, but this is actually a moot point, because as soon as it starts optimization, the compiler just moves a couple of lengths between the stack and the registers.