#c#
#c#
Вопрос:
Учитывая фрагмент кода
string S = "aa bb cc...";// very long string
foreach(var w in S.Split()){// <-- how many invoke for Split() ?
// (Edited: After writing extension Method to test,
//it is invoked once.)
//do something
}
Есть ли какие-либо проблемы с производительностью для приведенного выше кода? Нужно ли мне переписать это, как показано ниже?
string S = "aa bb cc...";
var strArray = S.Split();
foreach(var w in strArray){
//do something
}
Комментарии:
1. ericlippert.com/2012/12/17/performance-rant
2.
how many invoke for Split() ?
Один.3. Обе версии вашего кода будут работать одинаково.
4. Для такого рода вопросов всегда задавайте себе вопрос «как бы я это протестировал?» Вы могли бы, например, написать свою собственную
Split2
функцию, поместить в нее точку останова, а затем посмотреть, сколько разSplit2
вызывается. И вы увидите, что ответ один.5. Они фактически одинаковы, да.
Ответ №1:
Когда я компилирую обе версии вашего кода с включенной оптимизацией, я получаю тот же IL:
IL_0000: ldstr "aa bb cc ..." IL_0005: вызов системы.Массив.Пусто IL_000A: система callvirt.Строка.Разделение IL_000F: stloc.0 IL_0010: ldc.i4.0 IL_0011: stloc.1 IL_0012: br.s IL_001C IL_0014: ldloc.0 IL_0015: ldloc.1 IL_0016: ldelem.ref IL_0017: pop IL_0018: ldloc.1 IL_0019: ldc.i4.1 IL_001A: добавить IL_001B: stloc.1 IL_001C: ldloc.1 IL_001D: ldloc.0 IL_001E: ldlen IL_001F: conv.i4 IL_0020: blt.s IL_0014 IL_0022: ret
Между этими двумя версиями кода нет разницы (при оптимизации).
Ответ №2:
Оба фрагмента кода генерируют один и тот же код. Посмотрите на вывод декомпилятора (в данном случае ILSpy):
В конфигурации ОТЛАДКИ (без оптимизации кода);
string s = "aa bb cc...";
// foreach (string w in s.Split())
string[] array = s.Split();
foreach (string w in array)
{
Console.WriteLine(w);
}
и
string s = "aa bb cc...";
// var stringArray = s.Split() ...
// foreach(var w in stringArray)
string[] stringArray = s.Split();
string[] array = stringArray;
foreach (string w in array)
{
Console.WriteLine(w);
}
Итак, вы можете видеть, что второй фрагмент создаст еще одну ссылку на массив строк, что не должно иметь большого значения.
В режиме ВЫПУСКА (с оптимизацией кода) дополнительная ссылка ( array
) будет удалена, поэтому оба фрагмента генерируют тот же код, что и foreach (string w in s.Split())