書かない理由はなんだろう
list.Count.Equals(0)
あなたがおそらく書くとき
list.Count == 0
技術的/意味的な理由はありますか?
この特定のケースでは、2 つのステートメントに違いはないと思います。int
値の等価性をチェックしているため。==
演算子とEquals
まったく同じ操作を行います。
ただし、次のケースなど、他のケースでは、異なる値が返される場合があります。
Double.NaN == Double.NaN // is false
Double.NaN.Equals(Double.NaN) // is true
一般に、値の型には==
;を使用できます。ただし、参照型の場合は、 を使用することをお勧めしEquals
ます。
int
サンプルの分解については、以下に表示されています。生成されたアセンブリ コードが異なるため、パフォーマンスが異なることが予想されます。
int a = 10;
00000080 mov dword ptr [ebp-40h],0Ah
int b = 9;
00000087 mov dword ptr [ebp-44h],9
bool x = a == b;
0000008e mov eax,dword ptr [ebp-40h]
00000091 cmp eax,dword ptr [ebp-44h]
00000094 sete al
00000097 movzx eax,al
0000009a mov dword ptr [ebp-48h],eax
bool y = a.Equals(b);
0000009d lea ecx,[ebp-40h]
000000a0 mov edx,dword ptr [ebp-44h]
000000a3 call 6B8803C0
000000a8 mov dword ptr [ebp-60h],eax
000000ab movzx eax,byte ptr [ebp-60h]
000000af mov dword ptr [ebp-4Ch],eax
主な理由は2つ
list.Count == 0 の方が読みやすい (最も重要)
list.Count.Equals(0) は遅い
list.Count == 0
読みやすさが向上し、imoが短くなります。パフォーマンスがごくわずかである場合は、常に読みやすいものを使用し、意図を最も明確に示してください。
技術的な理由について:生成された2つのILシーケンスを比較する場合。
IL_0029: callvirt instance int32 class [mscorlib]System.Collections.Generic.List`1<string>::get_Count()
IL_002e: stloc.s CS$0$0001
IL_0030: ldloca.s CS$0$0001
IL_0032: ldc.i4.0
IL_0033: call instance bool [mscorlib]System.Int32::Equals(int32)
// Equals(obj int) internally uses the method this == obj;
対。
IL_007f: callvirt instance int32 class [mscorlib]System.Collections.Generic.List`1<string>::get_Count()
IL_0084: ldc.i4.0
IL_0085: ceq
==演算子は使用する命令が少ないため高速であると主張する人もいるかもしれませんが、どのように最適化されるかは誰にもわかりません。
JITウォームアップと、最初に呼び出されるさまざまなシーケンスを使用してクイックベンチマークを実行すると、(少なくとも私のマシンでは)100000000要素を超える反復で、==が約25ミリ秒高速であることがわかります。