I think it's quite obvious if you look at the disassembly:
The IList
version is compiled to:
for (int i = 0; i < 1000000000; i++)
0000003d xor edi,edi
{
count = lst.Count;
0000003f mov ecx,esi
00000041 call dword ptr ds:[00280024h]
00000047 mov ebx,eax
for (int i = 0; i < 1000000000; i++)
00000049 inc edi
0000004a cmp edi,3B9ACA00h
00000050 jl 0000003F
}
The access to IList.Count
is compiled into a call
instruction.
The List
version on the other hand is inlined:
for (int i = 0; i < 1000000000; i++)
0000003a xor edx,edx
0000003c mov eax,dword ptr [esi+0Ch]
0000003f mov esi,eax
00000041 inc edx
00000042 cmp edx,3B9ACA00h
00000048 jl 0000003F
}
No call
instruction here. Just a mov, inc, cmp and jl instruction in the loop. Of course this is faster.
But remember: Usually, you're doing something with the contents of your list, you're not just iterating over it. This will usually take much longer than a single function call, so calling interface methods will rarely cause any performance problems.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…