Comments 30
Молодец, хорошее исследование на тему boxing/unboxing. Насчет R# совет: его warning на redundant .ToString() call можно заменить на hint или suggestion. И видно, и глаз радуется зеленому индикатору.
+1
Спасибо за статью. Буду теперь везде юзать ToString().
-2
Не, ну я понимаю, безударные гласные, одна/две буквы «н», даже ошибку в тся/ться я могу понять. Но откуда у людей в голове берется этот «ВЫЙГРЫШ» я понять не смогу никогда.
+9
Вообще, ToString() про перегруженых операциях лучще юзать почаще, т.к. его отсутствие временами порождает неочевидные(по крайней мере в первый раз, когда с этим сталкиваешься) неявные преобразования. Из наиболее известного:
string vals = «AAAAA»;
int val1 = 10;
int val2 = 11;
Console.WriteLine(vals[1] + val1 + ":" + val2); // Упс! :)
Console.WriteLine(vals[1].ToString() + val1 + ":" + val2); // Совсем другое дело.
Console.ReadLine();
string vals = «AAAAA»;
int val1 = 10;
int val2 = 11;
Console.WriteLine(vals[1] + val1 + ":" + val2); // Упс! :)
Console.WriteLine(vals[1].ToString() + val1 + ":" + val2); // Совсем другое дело.
Console.ReadLine();
0
По-моему этому учат ещё на первых курсах при упоминаниях string'ов — левая операнд задаёт тип результата:
- string + int = string
- int + int = int
- int + string = error
0
левый операнд, конечно же
*slfx — сначала было «левая часть»…
*slfx — сначала было «левая часть»…
0
И как тот факт, что char+int = int вписывается в вашу концепцию?
Вы код запускали ввобще?
>>int + string = error
string s = 12 + «qqq»; // No errors… Magic?
>>По-моему этому учат ещё на первых курсах
Мне кажется, вы не слишком на лекциях усердствовали :D
Вы код запускали ввобще?
>>int + string = error
string s = 12 + «qqq»; // No errors… Magic?
>>По-моему этому учат ещё на первых курсах
Мне кажется, вы не слишком на лекциях усердствовали :D
0
С моими лекциями и присутствием на них было всё в порядке. Спасибо, что поинтересовались.
Однако хотелось бы подчеркнуть что мой комментарий был реакцией на вполне конкретный пример. Чар и инт, собственно, там одно и то же. Смысл в написании код и понимании как он будет читаться (машиной). Я думаю ни для кого не секрет что у каждого выражения будет своё значение: 1 + «2» + 3 + 4, 1 + 2 + «3» + 4, 1 + 2 + 3 + «4», 1 + 2 + 3 + 4.
П.С.: магии нет — есть разные языки и их ревизии со своим отношением к explicit/implicit.
Однако хотелось бы подчеркнуть что мой комментарий был реакцией на вполне конкретный пример. Чар и инт, собственно, там одно и то же. Смысл в написании код и понимании как он будет читаться (машиной). Я думаю ни для кого не секрет что у каждого выражения будет своё значение: 1 + «2» + 3 + 4, 1 + 2 + «3» + 4, 1 + 2 + 3 + «4», 1 + 2 + 3 + 4.
П.С.: магии нет — есть разные языки и их ревизии со своим отношением к explicit/implicit.
0
>>>Однако хотелось бы подчеркнуть что мой комментарий был реакцией на вполне конкретный пример.
Ну да, ну да… Я это сразу понял после вашего «int + string = error». :)
>>Чар и инт, собственно, там одно и то же.
Безусловно! Г-н Хейлсберг, всё время хотел у Вас спросить — отчего это разные типы?
Ну да, ну да… Я это сразу понял после вашего «int + string = error». :)
>>Чар и инт, собственно, там одно и то же.
Безусловно! Г-н Хейлсберг, всё время хотел у Вас спросить — отчего это разные типы?
0
Статья хорошая. Главный вывод из нее, как мне кажется — «используйте ToString() в тех случаях, когда это выгодно». А во всех остальных случаях я предпочту более компактный код.
+5
главное ведь не то, насколько он компактный (иначе вы б не использовали «многословный» С#, а предпочли бы, к примеру, APL/J/K). главное насколько код удобочитаемый. для меня someInt + someString не настолько понятный код, как someInt.ToString() + someString (но это субъективно, конечно). а если, к тому же, более понятный код оказывается более эфективным, то я просто не вижу причин его использовать… (и только не нужно говорить, что набирать меньше. большинство проггеров на .ToString() тратят меньше секунды времени).
0
Всё относительно. Если есть узкое место, то его нужно оптимизировать, а добавлять во всех случаях, а не только для структур, вызов ToString() — это уже преждевременная оптимизация.
P.S. Кстати интересно, Resharper выдаёт предупреждение на код, находящийся в цикле, или на единичный вызов, или и там и там?
P.S. Кстати интересно, Resharper выдаёт предупреждение на код, находящийся в цикле, или на единичный вызов, или и там и там?
0
У меня выдавал на единичный вызов, но это как сказали выше настраивается.
+1
Понятно, что настраивается. Просто интересно, если поместить тот же вызов в цикл, Resharper по умолчанию продолжит выдавать предупреждение или сочтёт что в цикле лучше оставить ToString()?
0
Да он всегда ругается, я когда писал примеры кода, точно помню, в цике он мне ToString() выделял серым и говорил, что его можно не вызывать.
0
а как тот факт, что вызов в цикле или нет может влиять на «суждения» решарпера? если даже это единичный вызов в методе, то сам метод может вызываться в цикле.
0
Сколько текста из-за обиды на решарпер :)
Но статья хороша, спасибо!
Но статья хороша, спасибо!
0
Использование ToSting() в скором времени приводит к тому, что он начинает плодиться по всему коду, и его вызывают просто на всякий случай, и это приводит к тому, что выигрыш, полученный в одном методе, тратится на 10 излишних вызовов в других (по крайней мере, в 80% код ревью, в которых приходилось участвовать, то было так).
Использование конкатенации (+ в С# или string.Concat) строк метод, имеющий право на жизнь, но я бы рекомендовал не использовать его как «волшебную палочку». Если реально код дожен быть более производительным — используйте StringBuilder. В той же книге Рихтера объясняется почему (вкратце, потому что этот класс по другому работает с массивом char). Например, немного модифицированный пример (чтобы строка постоянно росла).
var time = Stopwatch.StartNew();
string s = «habrahabr»;
for (int i = 0; i < 100000; i++)
{
s += i.ToString();
}
Console.WriteLine(time.Elapsed.ToString());
time = Stopwatch.StartNew();
StringBuilder sb = new StringBuilder();
sb.AppendFormat(«habrahabr»);
for (int i = 0; i < 100000; i++)
{
sb.Append(i);
}
Console.WriteLine(time.Elapsed.ToString());
дал следующие результаты:
00:01:10.4000846
00:00:00.0314729
Если не касаться производительности, то использование конкатенации здорово усложняет жизнь при локализации приложений.
ЗЫ. С темой упаковки/распаковки — поддерживаю автора на все сто
Использование конкатенации (+ в С# или string.Concat) строк метод, имеющий право на жизнь, но я бы рекомендовал не использовать его как «волшебную палочку». Если реально код дожен быть более производительным — используйте StringBuilder. В той же книге Рихтера объясняется почему (вкратце, потому что этот класс по другому работает с массивом char). Например, немного модифицированный пример (чтобы строка постоянно росла).
var time = Stopwatch.StartNew();
string s = «habrahabr»;
for (int i = 0; i < 100000; i++)
{
s += i.ToString();
}
Console.WriteLine(time.Elapsed.ToString());
time = Stopwatch.StartNew();
StringBuilder sb = new StringBuilder();
sb.AppendFormat(«habrahabr»);
for (int i = 0; i < 100000; i++)
{
sb.Append(i);
}
Console.WriteLine(time.Elapsed.ToString());
дал следующие результаты:
00:01:10.4000846
00:00:00.0314729
Если не касаться производительности, то использование конкатенации здорово усложняет жизнь при локализации приложений.
ЗЫ. С темой упаковки/распаковки — поддерживаю автора на все сто
+2
где-то читал конкатенация через +, дает выигрыш в сравнении со StringBuilder, если количество слагаемых не привышает 8, если элементов больше, то StringBuilder здесь лидер.
0
Это точно, отладка тоже очень важный фактор… учитывая тот фактор, что заметная разнича только на миллионах и только с большими структурами, то лучше иметь красивый код в случае единичного использования или не очень большом цикле.
Автору спасибо, интересно было узнать :)
Автору спасибо, интересно было узнать :)
+1
UFO just landed and posted this here
Сначала не понял — R# это вроде как метапрограммистский проект на RSDN. Что касается решарпера, то да, у него есть ряд таких «коррекций», которые являются ошибочными. Например удаление пустого статического дефолтного конструктора.
0
Спасибо за статью, но…
Раньше тоже страдал такими вот «выигрышами» (да и сейчас нередко)… Но после плотной работы с оптимизацие производительности, понял, что такие выигрышы ничего не стоят. Даже самый «толстый» вызов стоит микросекунды, так что бороться здесь просто не за что. А если они становятся проблемой — значит проблема где-то выше.
Раньше тоже страдал такими вот «выигрышами» (да и сейчас нередко)… Но после плотной работы с оптимизацие производительности, понял, что такие выигрышы ничего не стоят. Даже самый «толстый» вызов стоит микросекунды, так что бороться здесь просто не за что. А если они становятся проблемой — значит проблема где-то выше.
0
Sign up to leave a comment.
Прав ли R#: call to .ToString() is redundant?