- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
sub exdef {
my ($hash, $key) = @_;
if (exists $hash->{$key} && defined $hash->{$key}) {
return 1;
}
return 0;
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−103
sub exdef {
my ($hash, $key) = @_;
if (exists $hash->{$key} && defined $hash->{$key}) {
return 1;
}
return 0;
}
No comments.
BTW.
http://perldoc.perl.org/functions/exists.html
http://perldoc.perl.org/functions/defined.html
autovivification, насколько я понимаю, срабатывает в случаях, когда нужно получить доступ к следующему уровню хеша - т.е. defined $hash->{'a'}{'b'} добавит ключ 'a' в $hash. Но ключ 'b' добавлять не будет. В нашем же случае он ничего не добавит, т.к. autovivification не действует на последний уровень.
http://ideone.com/hkbIfG
Но данный бенчмарк не совсем подходит, т.к. здесь тестируются defined и exists по-отдельности. exists не спаренный с defined естественно будет работать быстрее, нежели defined, тут я не спорю, в defined'е чуть больше проверок.
Но пара exists+defined написанная на перле ну никак не может быть быстрее, чем defined, полностью написанный на си.
Глупости какие-то пишете.
Используется and, но с && тоже самое: http://pastebin.com/kZKeVAe9
Rate exdef defined exists
exdef 2994012/s -- -35% -40%
defined 4608295/s 54% -- -8%
exists 5025126/s 68% 9% --
Проценты варьируются +-10% от запуска к запуску, но дабы побыстрее.
Да я прекрасно знаю, что && он short-circuit. Поэтому я и написал, что в случае когда ключ не определен, то defined+exists в принципе догонит exists по скорости (равно как и одинокий defined, в котором подобная логика все равно есть).
> -40%.
Ага. Т.е. exists+defined мало того что говно, так еще и медленное? ;)
Тем не менее, не смотря на то, что кажется на говнокода такая проверка нужна порой: высоконадежный софт всегда с использованием use warnings.
Прокачили скилл и это хорошо :)
Какие еще варнинги?! Мы же не передаем никуда этот элемент, а только проверяем на определенность: https://ideone.com/65cORh.
UPD. Если передавать - конечно будут https://ideone.com/HZl7K6. Но вот только defined тут совершенно не причем. Все франкенштейны, составленные из них только работают медленнее, и выглядят запутаннее.
Так что логика верная, но верить перлу нельзя никогда. Бенчи-бенчи-бенчи :)
Когда я пишу на крестах (а они считаются достаточно низкоуровневыми), я практически не задумываюсь об микрооптимизациях, и пишу как проще и понятней - компилятор умеет инлайны на дохера уровней, неплохо знает особые команды типа lea, библиотеки уже сами по себе неплохо задрочены на производительность и т.п. И для достаточной производительности почти всегда достаточно не тупануть с алгоритмами и структурами данных.
В то же время на так называемых "высокоуровневых языках" уже в который раз вижу примеры, когда пишущие на них начинают выдрачивать производительность (а раз они это делают, значит ее действительно не хватает, не будут же они заниматься преждевременной оптимизацией, или оптимизацией не в том месте).
Так вот и получается, что низкоуровневый язык по сути дает более понятный код, нежели высокоуровневые, за счет того, что в погоне за скоростью высокоуровневый код превращают в говно...
P.S. Хотя, скорее всего, проблема со скоростью defined'а надуманная, т.к. он занимает всего 96нс, а тот же цикл вокруг него и т.п. запросто могут занять больше времени чем все эти проверки...
Кстати, а профайлер в перле есть? Чтобы править не то, что кажется медленным, скатывая код в говно, а видеть именно хотспоты?
Сам не пользовался им никогда.
Почему? Профайлеры же очень годная штука, позволяющая расставить приоритеты по оптимизации кусков проекта... Мне нравится для крестов его юзать ;) Экономит просто гору времени...
P.S. А без профайлера можно всю жизнь менять " на ', думая, что они работают быстрее. А на деле это даст жалкие 2% прироста производительности, которые нафиг никому не сдались, если можно выиграть в другом месте все 200...
Пока руки не дошли. Сейчас вот смотрю видео про nytprof: http://blip.tv/timbunce/devel-nytprof-v4-oscon-201007-3932242
Начну пользоваться. Тут еще зависит где работаешь и как работаешь :) У меня последнее время было - пиши код, главное надежность, а оптимизации шли в последнюю очередь. Вопрос надежности кода в перле не менее увлекательное занятие чем профилирование, я уверен. Особенно с XS-кодом.
Была бага в одном модуле, утечка: пока искал, 4 раза переписал свое приложение (ушел почти месяц), стопитсот раз оптимизировал, а потом решил удалять все потихоньку, нашел бажный модуль. Запустил valgrind - ничего, gdb - куча кишков на си, считаю ref counts.. Задумался на 10 минут, прикинул где и куда может течь - исправил одну строчку и нет утечек :)
Респект ;)
> Вопрос надежности кода в перле не менее увлекательное занятие чем профилирование
Вот поэтому для меня перл так и останется языком для мелких говноскриптиков, которые я люблю на нем писать ;)
> решил удалять все потихоньку
Кстати, судя по опыту, самый эффективный способ поиска гейзенбагов.
Для мелких скриптов - язык очень приятный. Пишутся быстро, работают достаточно шустро. Модулей хороших на CPAN'е полно.
Но вот стоит начать писать что-то чуть-чуть побольше, даже с парой-тройкой своих модулей, как все достоинства перловки сразу же превращаются в почти фатальные недостатки... Те же классы у меня, к примеру, вызывают отвращение. Конструкции типа $hash->{$key} начинают выбешивать, т.к. даже в крестах это просто hash[key] или struct.field. А те приятные фишки, которые юзались в маленьком коде, юзать страшно, т.к. поддерживать их потом сложновато...
В итоге более-менее надежный код по логике откатывается к си\с++\жабе, а по синтаксису получается намного хуже и длиннее чем на тех самых языках ;(
Ну это тебе так кажется. Кода на си для чего-то очень серьезного, скажем для того же DBD::Oracle у тебя на си получится в разы больше. Ладно, скажешь что заюзаешь потоки и этим выйграешь в скорости. Но допустим можно в перле будет воспользоваться форком и тогда перл покажет все свои прелести.
Я писал разные приложения. Средний размер сейчас у меня от 500 до 1500 строк. Самое большое овер 10 тыс. строк на одно приложение, несколько десятков модулей и куча функционала: snmp, telnet, логирование на уровне log4j, работа с БД, использование кэшей и т.д. и т.п. Писалось в довольно короткие сроки (месяц с лишним) - почти 3 тыс строк, функционал сейчас наращивается вообще влет. А на си сколько бы я это отлаживал? :)
Вообще судя по тому как тот же Tim Bunce (автор DBI, DBD::Oracle, Devel::NYTProf) рулит и педалит своей компанией, я бы не сказал, что на перле нельзя писать что-то сложное. Можно, только чтобы стать как он надо знать си, мозги, потратить н-лет на разработку в разных проектах и может тогда что-то дельное получится.
Есть еще относительно новый чел - Mark Lehmann (AnyEvent, EV, libev - аналог libevent). Этот чел вообще маньяк :) С его уровнем знаний си(++) вроде как перл ему и не нужен. Но как видно - пишет и очень активно.
Это к тому, что тот кто считает, что перл мертв и для неудачников - просто не умеют его как следует готовить, имхо. И да, си рулит везде.
Ну и си все-таки сравнивать не совсем корректно, немного не тот уровень. А вот тот же с++ по поддерживоемости будет ну никак уж не хуже перловки.
Про опыт согласен. Прокачанный программист на своем языке может творить чудеса...
А напомните, пожалуйста, чем там форк отличается? Там не системный, а свой планировщик, и можно запустит под сотню таких "процессов", если они не будут зависать в сишном апи? Если ьак то да, на си это проблематично. На крестах - boost::asio с подобными задачами споавлется. Но там асинхронная лапша со всеми вытекающими. Зеленые треды все-таки поприятней.
Вы не поняли. Short-circuit не работает в этом случае. У меня 5.12.4 из поставки Debian Squeeze. Если взглянуть на код ниже, как я показал разделить в два if'а, то мой бенч показывает отставание от exists в 4%.
Не могу найти баг в трекере, видимо надо постить.
:)
Вообще писать без скобок все подряд считается плохим стилем by design. Ну и для общего развития, трудности перла, описаны [url=http://www.perlmonks.org/?node_id=663393]тут[/url]
Вот за это плюсану. Я в перле всегда пишу скобки. Абсолютно всегда. В конце концов набираю я быстро, парсер у перла достаточно шустрый, и 2 байта ради непонятно чего экономить совсем влом.