【发布时间】:2012-05-08 18:38:15
【问题描述】:
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 在我的计算机上运行的影响。另外,与空字符串比较的测试结果相同,比 IsNullOrEmpty 慢约 13%。)
此外,为什么IsNullOrEmpty 仅在 x86 上更快,而在 x64 上String.Length 大约快 9%?
更新: 测试设置详情:.NET 4.0 在 64 位 Windows 7、Intel Core i5 处理器、编译时启用“优化代码”的控制台项目上运行。但是,还启用了“在模块加载时抑制 JIT 优化”(请参阅接受的答案和 cmets)。
在完全启用优化的情况下,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
【问题讨论】:
-
在不知道您所处的确切情况的情况下,我相当有信心,在大多数情况下,还有其他优化可以解决,而不是检查字符串是否没有任何数据的最快方法在里面。
-
@minitech 因为有 4 个测试人员,而且他是独立计时的。
-
Empty和==与Length和IsNullOrEmpty相比如何? -
尝试将 s.Length == 0 更改为 Convert.ToBoolean(s.Length) 这会提高性能吗?
-
@Andrew 我同意这种差异并不显着,除非空检查占执行时间的很大比例。我只是好奇,现在我更加好奇了。
标签: c# .net string performance is-empty