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 上更快,而在 x64 上String.Length
却快 9%?
更新:测试设置详细信息:.NET 4.0 在 64 位 Windows 7、Intel Core i5 处理器、编译时启用“优化代码”的控制台项目上运行。但是,还启用了“抑制模块加载时的 JIT 优化”(请参阅接受的答案和评论)。
在完全启用优化的情况下,Length
比IsNullOrEmpty
删除委托和其他开销的速度快 14%,如下所示:
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