Почему String.IsNullOrEmpty быстрее, чем String.Length?

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();
}

(Другие тесты показывают аналогичные результаты. Это минимизировало эффект запуска хлама на моем компьютере. Кроме того, тесты по сравнению с пустыми строками оказались одинаковыми примерно на 13% медленнее, чем IsNullOrEmpty.)

Кроме того, почему IsNullOrEmptyбыстрее только на x86, тогда как на x64 String.Lengthпримерно на 9% быстрее?

Обновление:Сведения о настройке теста :.NET 4.0, работающий на 64-разрядной -Windows 7, процессор Intel Core i5, консольный проект, скомпилированный с включенной функцией «Оптимизировать код». Однако также была включена функция «Подавлять 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
19
задан Edward Brey 28 April 2012 в 21:00
поделиться