суббота, февраля 24, 2007

Down to the roots

Любопытно сравнить скорость выполнения двух методов C#-класса:

private string BinaryToHex(byte[] Data)
{
string res = "'0x";

for(int a = 0; a < Data.Length; a++)
res += Data[a].ToString("X2");

return String.Format("{0}'", res.Replace("%", ""));
}
и
private string BinaryToHex(byte[] Data)
{
char[] res = new char[Data.Length * 2];

for(int a = 0; a < Data.Length; a++)
{
string str = Data[a].ToString("X2");
res[a * 2] = str[0];
res[a * 2 + 1] = str[1];
}

return String.Format("'0x{0}'", new string(res));
}
.

Второй работает быстрее первого - на порядок, хотя, на первый взгляд, и не должен. Почему? Причина в конкатенации строк. Это настолько медленная операция, что код должен обязательно проверяться на её наличие, особенно в потенциально больших циклах.

4 комментария:

Анонимный комментирует...

Ты меня разочаровываешь.
Еще лет 5 назад, проводя собеседования с веб(!)-программистами в Альтере, я в частности задавал примерно такой вопрос:
Почему медленно работает следующий Javascript-код и как путем минимальных изменений заставить его работать на два порядка быстрее:
var s = "";
for( var i = 0; i < 100000; i++ )
{
s += "Какая-то динамически формируемая строка";
}
//Тут что-то делаем со всей строкой типа alert( s );

Das Ich комментирует...

"У всех свои недостатки"

Анонимный комментирует...

А если StringBuilder поюзать ? ;)

Das Ich комментирует...

Поюзайте. Я не возражаю.