- 1
- 2
- 3
- 4
- 5
private static int NumberOfLeadingSpaces(string str)
{
str = str.TrimEnd();
return str.Length - str.Trim().Length;
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+91
private static int NumberOfLeadingSpaces(string str)
{
str = str.TrimEnd();
return str.Length - str.Trim().Length;
}
Из моего проекта. Так я писал код 1.5 год назад.
Вместо того, чтобы пройтись циклом с начала строки, пока не встретиться символ, не являющийся пробелом.
Но... зачем? Типа только потому, что так быстрее?
И логику лучше видно, чем в этой фигне с тримами. На самом деле там надо бы какую-нибудь функцию для поиска "первого не пробела", но я шарп плохо знаю, поэтому название не скажу.
Чё-то не сильно лучше видно. Да и не особо быстрее, как оказалось. Ну да ладно.
Да почему - ищем первый не пробел и возвращаем его позицию. А вот из кода ОП'а это хер выведешь, имхо.
P.S. А у версии с Linq какая производительность?
P.P.S. Кто ж так бенчит? Надо хотя бы 1000 раз в цикле...
Ну, как бы, понятно то, что NumberOfLeadingSpaces и "позиция первого непробела" – это одно и то же. Но всё равно, меня как-то напрягает такая трактовка, не знаю почему (хотя знаю, но мне стыдно в этом признаться).
>А у версии с Linq какая производительность?
Не знаю, не тестила. Смею предположить, что медленнее. Надо попробовать.
Счёт через String.Trim() и String.Length в среднем занял 0,000193833333333321
Счёт через цикл в среднем занял 0,000176633333333322
Счёт через LINQ в среднем занял 0,000504066666666807
А разность длин тримнутой и нетримнутой строк не напрягает? ;)
Кстати, цикл не эквивалентен - табы не режет.
Окей, поправила. Замеры выше – с учётом фикса.
P.S. Имхо, не стоит заниматься такими микрооптимизациями без повода.
А оптимизировать или нет - ну так мы ж тут уже начали бенчмарками мерятся и т.д.... как же так, не оптимизировать?
Да там поди есть TrimStart(), раз TrimEnd() нашёлся.
Счёт через String.TrimStart() и String.Length в среднем занял 0,000138488888888883
Счёт через цикл в среднем занял 0,000117655555555551
Счёт через LINQ в среднем занял 0,000455677777777891
Счёт через цикл в среднем занял 0,00016739999999999
Счёт через LINQ в среднем занял 0,000532255555555699
Счёт через регулярку в среднем занял 0,00101864444444456
Получилось медленнее всего.
Результат: 0,0001771 :)
Была дана строка:
Счёт через String.TrimStart() и String.Length в среднем занял 0,000243334047349131
Счёт через цикл for в среднем занял 0,000307815206661784
Счёт через цикл foreach в среднем занял 0,000313723992773795
Счёт через LINQ в среднем занял 0,000482685286941327
Счёт через регулярку в среднем занял 0,00152696509397179
Была дана строка:
Счёт через String.TrimStart() и String.Length в среднем занял 0,000143253022146697
Счёт через цикл for в среднем занял 0,000161914429936376
Счёт через цикл foreach в среднем занял 0,000175021420455629
Счёт через LINQ в среднем занял 0,000261402201651063
Счёт через регулярку в среднем занял 0,000844150352972605
Была дана строка:
.
Счёт через String.TrimStart() и String.Length в среднем занял 0,000127726451468525
Счёт через цикл for в среднем занял 0,000174751336450242
Счёт через цикл foreach в среднем занял 0,000142662562631326
Счёт через LINQ в среднем занял 0,000235014994319443
Счёт через регулярку в среднем занял 0,000746058636169464
Результат: 0,0003608 :)
Результат: 0,0006230 :)
Счёт через String.TrimStart() и String.Length в среднем занял 0,00016589164974754
Счёт через цикл for в среднем занял 0,000193916590608682
Счёт через цикл foreach в среднем занял 0,000158231508558716
Счёт через LINQ в среднем занял 0,000260426639596914
Счёт через регулярку в среднем занял 0,000849728519009069
Счёт через IEnumerable.AsParallel() в среднем занял 0,0568745259559993
Правда, TakeWhile() можно было бы заменить на ForAll() и условия в лямбде.
даёт 0,0041484, в вот этот (без индекса):
даёт 0,0052 (в среднем). В чём фишка? o_O
http://pastebin.com/urZPZMSe
При тысяче пробелов и миллионе повторов у моего старенького ноутбука памяти не хватат (2 гига).
http://pastebin.com/9Amg4Fvn
Это результаты, если кому интересно.
Я щетаю, AssParallel всех нагнул!
А если серьёзно, то цикл for без лишнего if явный фаворит. Он обогнал даже unsafe код.
Странно.
Неужели для осознания простого факта что императивный for рулит, необходимо написать несколько десятков комментов и проводить кучу тестов?
ОПу как и мне это было очевидно сразу.
Хотелось бы иметь возможность отключить эти проверки. Что-то типа AsUnchecked, по аналогии с AsParallel.
Это он дополнительные проверки убирает, в a[i], к примеру. Но он с тем же успехом убирает ее и из цикла.
Ну тут хотя бы частные случаи можно оптимизнуть, когда индекс внутри цикла не меняют и условие остановки удобоваримое.
P.S. Гцц вроде бы даже переворачивало цикл вверх-ногами, если результат не влияет на ответ.
А зачем? Почему часто обходят наоборот?
Вывод добавил для тех, кому лень просматривать и сравнивать десятки строк результата.
А главное, я хотел показать, что одну скорость сравнивать мало смысла: важны и сборки мусора и потребляемая память.