ILSpyは、String.IsNullOrEmpty
がで実装されていることを示していString.Length
ます。しかし、なぜString.IsNullOrEmpty(s)
より速いのですs.Length == 0
か?
たとえば、このベンチマークでは5%高速です。
var stopwatches = Enumerable.Range(0, 4).Select(_ => new Stopwatch()).ToArray();
var strings = "A,B,,C,DE,F,,G,H,,,,I,J,,K,L,MN,OP,Q,R,STU,V,W,X,Y,Z,".Split(',');
var testers = new Func<string, bool>[] { s => s == String.Empty, s => s.Length == 0, s => String.IsNullOrEmpty(s), s => s == "" };
int count = 0;
for (int i = 0; i < 10000; ++i) {
stopwatches[i % 4].Start();
for (int j = 0; j < 1000; ++j)
count += strings.Count(testers[i % 4]);
stopwatches[i % 4].Stop();
}
(他のベンチマークも同様の結果を示しています。これは、私のコンピューターで実行されているcruftの影響を最小限に抑えました。また、余談ですが、空の文字列と比較したテストは、同じように約13%遅くなりIsNullOrEmpty
ました。)
さらに、なぜIsNullOrEmpty
x86でのみ高速であるのに対し、x64String.Length
では約9%高速なのですか?
更新:テストセットアップの詳細:64ビットWindows 7、Intel Core i5プロセッサ、「コードの最適化」を有効にしてコンパイルされたコンソールプロジェクトで実行されている.NET4.0。ただし、「モジュールロードでのJIT最適化の抑制」も有効になっています(承認された回答とコメントを参照)。
最適化を完全に有効にすると、次のテストのように、デリゲートやその他のオーバーヘッドを削除したLength
場合よりも約14%高速になります。IsNullOrEmpty
var strings = "A,B,,C,DE,F,,G,H,,,,I,J,,K,L,MN,OP,Q,R,,STU,V,,W,,X,,,Y,,Z,".Split(',');
int count = 0;
for (uint i = 0; i < 100000000; ++i)
count += strings[i % 32].Length == 0 ? 1 : 0; // Replace Length test with String.IsNullOrEmpty