LINUX.ORG.RU

Perl 5.20

 ,


3

8

Несколько часов назад состоялся релиз новой мажорной версии языка программирования Perl. Разработка Perl 5.20.0 заняла примерно 12 месяцев с момента выпуска Perl 5.18.0 и содержит около 470 000 строк изменений в 2 900 файлах от 124 авторов.

В этой версии достаточно много новшеств:

  • Subroutine signatures
    То, чего многие так ждали, а другие возражали привычным «ненужно»
    sub foo($bar, $baz) {
      print "\$bar=$bar, \$baz=$baz"
    }
    
    Таким образом теперь можно определять параметры функции в скобках после её имени. Есть и возможность задать значение по умолчанию
    sub bar($foo, $baz=10) {
      print '$foo+$baz=', $foo+$baz
    }
    
    О других особенностях новой экспериментальной возможности можно прочитать в perldoc perlsub. Стоит отметить, что старый механизм получения параметров функции из @_ также остаётся в силе.
  • Новый синтаксис для получения среза ключей-значений/индексов-значений для хешей/массивов
    %hash{...} и %array[...] соответственно
    %h = (blonk => 2, foo => 3, squink => 5, bar => 8);
    %subset = %h{'foo', 'bar'}; # срез ключ-значения для хеша
    # %subset теперь (foo => 3, bar => 8)
    
    @a = "a".."z";
    @list = %a[3,4,6]; # срез индекс-значения для массива
    # @list теперь (3, "d", 4, "e", 6, "g")
    
  • Постфиксное разыменовывание
    К старому доброму разыменовыванию ссылок, навроде @$foo и %$bar, был добавлен вариант постфиксного разыменовывания: $foo->@* и $bar->%* соответственно. Синтаксис для других типов ссылок можно посмотреть в perldoc perlref
  • Механизм копирования при записи (copy-on-write) для строк
    Теперь при присвоении переменной значения другой строковой переменной не создаётся копии буфера вплоть до тех пор, пока значение одной из переменных не будет изменено. Это увеличивает скорость присвоения и снижает потребление памяти. Теперь не потребуется передавать в функцию строковую переменную по ссылке, чтобы увеличить производительность.

>>> Подробности

★★★

Проверено: Aceler ()
Последнее исправление: cetjs2 (всего исправлений: 2)
Ответ на: комментарий от spy

язык медленный

4.2

скорость разработки - тоже

4.2

код нечитаемый

Во-первых, 4.2, во-вторых, код не обязан быть читабельным.

непортабельный

Портабельность не нужна.

burning_giraffes
()
Ответ на: комментарий от burning_giraffes

Портабельность не нужна.

На перловые оффсайты бы эту фразу.. а то apl заждался.

anonymous
()
Ответ на: комментарий от GOD

а что делать тем кто не разработчик и это не его поделия :))) ?

Если есть альтернативы - если есть возможность, выбирать программы на более строгих языках: pandoc / cheapskate заместо markdown.pl, например.

anonymous
()
Ответ на: комментарий от anonymous

Какую часть проекта (и на какой язык) приходилось переписывать, если не секрет?

Perl to SQL, PHP, Java.

PHP, bash, SQL, Java, MapBasic to Perl.

По проектам не знаю что сказать, много разной специфики. Скажу так - в основном все на Debian крутится, меняются работодатели и админы, а дистр прежний.

outtaspace ★★★
()
Ответ на: комментарий от outtaspace

Скорости хватает. Правильные алгоритмы и оптимизации

ну конечно. вот давайте посмотрим на то же расстояние левенштейна.

мало того, что реализация на чистом питоне быстрее perl-варианта(как разные варианты существующие в сети, так и Text::Levenshtein на CPAN), так еще можно взять pypy и ускорится раз 10-20.

В узких местах пишутся обертки над сишечкой.

это крайность. потому что вам тогда нужно иметь компилятор в системе, что на некоторых платформах если не проблематично, то весьма неудобно(если что, речь про windows).

Есть метрики? Любопытно.

врядли я могу вам представить какие-то метрики, но вот на моё предложение написать какой-нибудь эквивалент многопоточного grep, работающий на windows/posix как-то никто из перлистов не отозвался.

Портабельность - пока доволен.

а вы попробуйте писать код, одновременно работащий на linux/windows. хотя бы две платформы.

spy
()
Ответ на: комментарий от GOD

а что делать тем кто не разработчик и это не его поделия :))) ?

отказаться от опенсорса ?

Если вы вдруг на тестах вы находите проблему, то первое что нужно сделать - разобраться от каких изменении код сломался. Локализация проблемы в perldelta - это уже 90% решении задачи. А дальше дело техники - патчите сами проект, связываетесь с автором или обратитесь за помощью на форум программистов или фриланс-сайт. Разговоры о том что на perl код другого автора нечитаемый - это ложь. Лично я ни разу не испытывал сложности с разбором кода на perl. По субъективным оценкам код на perl разбирается быстрее чем на Си или Java.

anonymous
()
Ответ на: комментарий от spy

а вы попробуйте писать код, одновременно работащий на linux/windows. хотя бы две платформы.

Я писал в академических целях, причем влоб использовал низкоуровневые возможности (ioctl), хотя можно было и без этого. В одном месте мне пришлось использовать конструкцию

if($^O ne "MSWin32"){
 ...
}else{
 ...
}

хотите портируемый код - читайте man perlport

anonymous
()
Ответ на: комментарий от spy

ну конечно. вот давайте посмотрим на то же расстояние левенштейна.

Это сводится к оберткам на сишечке, о чем писалось. Или пусть поисковые движки этим занимаются, они под такое заточены.

это крайность. потому что вам тогда нужно иметь компилятор в системе

В некотором смысле это крайность. Увы, частенько бывают крайности. Наличие компилятора для меня проблемой не является, десктопный софт не пишу, только web и суровый server-side.

врядли я могу вам представить какие-то метрики

Вопрос исчерпан.

эквивалент многопоточного grep, работающий на windows/posix как-то никто из перлистов не отозвался

Ну, может не сильно оно и надо. Вот если за деньги не хотят, другой вопрос.

а вы попробуйте писать код, одновременно работащий на linux/windows. хотя бы две платформы

Писал и такой несколько раз, только server-side, проблем небыло. Пути к файлам, специфика работы с сокетами - все это модули скрывают от программиста. Да, те же вызовы внешних утилит могут быть проблемой, но тогда придется разные стратегии реализовывать на базе готовых модулей.

outtaspace ★★★
()
Ответ на: комментарий от anonymous

if($^O ne «MSWin32»){

ну вот это как раз ужасный путь. у меня в коде не было нигде проверок на какой платформе мы запустились. всё просто работало.

хотите портируемый код - читайте man perlport

отлично. и выкинем сразу половину вещей, потому что большая часть функций в perl являются отображением разных posix-штук.

spy
()
Ответ на: комментарий от spy

у меня в коде не было нигде проверок на какой платформе мы запустились

До поры до времени, пока зависите от своих уютных утилит/модулей. Как только появится экзотика от сторонних производителей, придется писать стратегии под конкретные платформы.

выкинем сразу половину вещей

Выкидывать нечего. Разве posix-совместимость это настолько плохо? Та же винда разве не posix-совместима?

outtaspace ★★★
()
Последнее исправление: outtaspace (всего исправлений: 1)
Ответ на: комментарий от outtaspace

Это сводится к оберткам на сишечке, о чем писалось

вы понимаете разницу между «ускориться в 10 раз, сменив интерпретатор» и написанием расширений на сишечке?

Или пусть поисковые движки этим занимаются, они под такое заточены.

простите, это тут причем? если вам в софте надо работать с текстом, причём тут поисковые движки?

ах, да. как в perl заменить стандартный движок регекспов на что-то другое без переписывания всего и вся?

десктопный софт не пишу, только web и суровый server-side.

оок. допустим, мы хотим написать сервер, обрабатывающий 30-60k коннектов. что для этого есть в perl? жалкий anyevent с лапшой коллбэков?

Пути к файлам, специфика работы с сокетами - все это модули скрывают от программиста.

имя сестра :) наверное, это всё надо тащить с cpan? :)

spy
()
Ответ на: комментарий от outtaspace

До поры до времени, пока зависите от своих уютных утилит/модулей.

в том и прелесть python, что в стандартной библиотеке есть почти всё что надо.

Разве posix-совместимость это настолько плохо? Та же винда разве не posix-совместима?

речь не о том что плохо. речь о том, что все платформозависимые вещи должны жить в отдельном модуле, а стандартная библиотека предоставлять адекватную абстракцию над ними.

например, наличие fork() в языке - это ужас. потому на windows начинаются жуткие костыли для его эмуляции.

и не надо рассказывать, что «windows - не нужно». там многие вещи сделаны весьма грамотно и намного лучше, чем в linux. увы.

а posix-подсистема в винде чисто для галочки и ставить надо её отдельно.

spy
()
Ответ на: комментарий от spy

вы понимаете разницу между «ускориться в 10 раз, сменив интерпретатор» и написанием расширений на сишечке?

Всего 10 раз? Ничего менять не буду. Не такое важное преимущество, можно написать либу, можно отдать задачу софтовому-микросерверу.

простите, это тут причем? если вам в софте надо работать с текстом, причём тут поисковые движки?

Некоторое количество лет я работал в компании занимающейся поиском, занимался мат-лингвистикой. Все сложные задачи выполняли и выполняют специальные инструменты - поисковые движки. Это я к чему? С текстом по разному можно работать: сложность алгоритмов, объемы данных, связность данных, планирование задач.

как в perl заменить стандартный движок регекспов на что-то другое без переписывания всего и вся?

Не настолько хорошо знаком с реализацией интерпретатора. Знаю что это можно. Один из моих коллег такое делал в качестве эксперимента, писал свой движок.

допустим, мы хотим написать сервер, обрабатывающий 30-60k коннектов. что для этого есть в perl? жалкий anyevent с лапшой коллбэков?

Пока с таким не сталкивался. Скорее всего возьму Erlang, там не будет anyevent (почему он жалкий?).

имя сестра :) наверное, это всё надо тащить с cpan? :)

Часть этих модулей есть в батарейке, а вы и не знаете. Ну чтож, таков ваш уровень.

outtaspace ★★★
()
Ответ на: комментарий от spy

в том и прелесть python, что в стандартной библиотеке есть почти всё что надо.

Вот я и обозначил пределы. Мое «пока» и ваше «почти» удачно сочетаются - рано или поздно узнаете свой уровень.

речь о том, что все платформозависимые вещи должны жить в отдельном модуле

С этим согласен. Ведь речь не о том что Perl это воплощенное совершенство?

например, наличие fork() в языке

Не важно где fork(), в built-in или в батарейке, важно как он реализован и как поддерживается/портируется. Разве не об этом речь? Костыли в эмуляции пусть остаются костылями слоя абстракции интерпретатора.

и не надо рассказывать, что «windows - не нужно»

Ну да. Мой выбор - мой набор плюшек и костылей.

outtaspace ★★★
()
Ответ на: комментарий от spy

if($^O ne «MSWin32»){

ну вот это как раз ужасный путь. у меня в коде не было нигде проверок на какой платформе мы запустились. всё просто работало.

Вы совсем не читаете что я пишу?

использовал низкоуровневые возможности (ioctl)

Предложите мне способ вызова ioctl без $^O ne «MSWin32» . Напомню что ioctl как и fork или fcntl является системным вызовом.

и не надо рассказывать, что «windows - не нужно». там многие вещи сделаны весьма грамотно и намного лучше, чем в linux. увы.

Интересно узнать, и какие же вещи сделаны намного лучше? Я считаю что windows - это уродливая платформа.

anonymous
()
Ответ на: комментарий от outtaspace

Всего 10 раз? Ничего менять не буду. Не такое важное преимущество, можно написать либу, можно отдать задачу софтовому-микросерверу.

однако. я даже не знаю как комментировать, если для вас десятикратное ускорение незначительно. кстати, ваш микросервер кто-то должен написать и отладить ещё. фактически, вместо одного языка нужно уже два.

Все сложные задачи выполняли и выполняют специальные инструменты - поисковые движки.

отлично. значит, городить еще один процесс рядом и rpc с ним. оно оправдано только если вы разом передаёте большой объём данных и с такой задачей вы сталкиваетесь постоянно.

Не настолько хорошо знаком с реализацией интерпретатора. Знаю что это можно.

ну видите ли, в python как-то принято иметь одинаковый(в крайнем случае, схожий) интерфейс с модулями из стандартной библиотеки. потому есть regex, для которого достаточно сказать import regex as re(либо вообще монкипатчить). аналогично с гугловским re2.

Скорее всего возьму Erlang, там не будет anyevent (почему он жалкий?).

и снова тут появляется второй язык. anyevent - из-за того что callback hell(а короутины в нём - это боль).

в python же есть gevent/eventlet.

Часть этих модулей есть в батарейке, а вы и не знаете. Ну чтож, таков ваш уровень.

ну ок, давайте про сокеты. где там в батарейках epoll?

spy
()
Ответ на: комментарий от anonymous

Интересно узнать, и какие же вещи сделаны намного лучше? Я считаю что windows - это уродливая платформа.

асинхронный i/o. в linux вы можете попасть в d-state при доступе к диску. если у вас event loop - это означает что всё встанет колом.

spy
()
Ответ на: комментарий от spy

если для вас десятикратное ускорение незначительно

Именно. В отрыве от контекста использования значительны только удобство и надежность.

разом передаёте большой объём данных и с такой задачей вы сталкиваетесь постоянно

Именно. Поэтому выше и написал что в некоторых случаях 10x это пшик. Были случаи, когда писал операторы для PostgreSQL, код ускорялся в сотни раз. Вот когда объемы данных большие, когда критичны задержки...

ну видите ли, в python как-то принято

Не аргумент. Культурные отличия. Важно так - можно или нет.

и снова тут появляется второй язык

Меня это не пугает. Достаточно много опыта.

в python же есть gevent/eventlet.

Не знал. Сяду учить питон, посмотрю. Впрочем уже интересно, посмотрю.

где там в батарейках epoll?

В батарейке нет IO::Epoll. Он ставится модулем с CPAN, как и IO::Poll. В батарейке есть IO::Select.

outtaspace ★★★
()
Ответ на: комментарий от spy

асинхронный i/o. в linux вы можете попасть в d-state при доступе к диску. если у вас event loop - это означает что всё встанет колом.

Да ничего особенного в асинхронном I/O под windows нет. В D state можно попасть и не только на I/O к диску. Код процесса вернется на исполнение процессором из D state если ошибок нет, а если ошибка - то это уже другой вопрос, и совсем не в пользу windows. Вы ни разу не встречали аналог «D state» под windows? - А я встречал, и не один раз. Вынужден констатировать что не всегда удается выполнить нормальную перезагрузку под windows (когда это удавалось сделать - рестарт занимал ненормально много времени).

anonymous
()
Ответ на: комментарий от spy

оок. допустим, мы хотим написать сервер, обрабатывающий 30-60k коннектов. что для этого есть в perl? жалкий anyevent с лапшой коллбэков?

Все зависит от того насколько глубоко вы готовы окунуться в своей разработке. Можно сделать prefork сервер на чистом perl, можно подключить EV (bind к libev), а можно части сервера рализовать на С и/или С++ прямо в модулях perl (выше я приводил пример с Inline::C). Вариантов множество, именно в этом смысл TIMTOWTDI.

anonymous
()
Ответ на: комментарий от spy

язык медленный

пруф пожалуйста.

anonymous
()

Перловочка

Посоны, а почему оно так долго в upstream Parrot'у льётся?!

Woofywoof
()
Ответ на: комментарий от anonymous

Да ничего особенного в асинхронном I/O под windows нет

в том и дело, что самого aio в linux как такового нет. а открывать файлы с O_DIRECT - это какое-то жесткое извращение.

В D state можно попасть и не только на I/O к диску. Код процесса вернется на исполнение процессором из D state если ошибок нет, а если ошибка - то это уже другой вопрос, и совсем не в пользу windows.

а подробнее? вот на linux есть epoll, который не умеет следить за файлами(обычный файл всегда готов к чтению или записи).

если у вас event loop и у вас всё прямо такое неблокирующее, то вызов какого-нибудь sendfile(а еще проще - read из файла) при отсутствии данных в кеше и медленных дисков весь этот event loop остановит.

так же всё легко может встать на open(), т.к. он тоже блокирующий. для этого люди либо плодят процессы, либо пулы тредов.

опять же, если мы периодически пишем большие объемы на диск, то тоже есть шанс «залипнуть», но тут хотя бы есть решения.

IOCP в windows гарантирует, что вы не заблокируетесь.

AIO еще есть в freebsd, но единственный, кто его использует - это nginx(и то, весьма нетрадиционным образом).

spy
()

Изменения хорошие, однозначно.

Deleted
()
Ответ на: комментарий от anonymous

сервер, обрабатывающий 30-60k коннектов

Можно сделать prefork сервер на чистом perl

да конечно, можно, только работать на такой нагрузке он не будет

впрочем, серьёзным перл-программистам, не способным показать ни один проект со своим участием, но учащих всех, как программировать, эти частности не мешают

anonymous
()
Ответ на: комментарий от spy

в том и дело, что самого aio в linux как такового нет. а открывать файлы с O_DIRECT - это какое-то жесткое извращение.

man aio ?

если у вас event loop и у вас всё прямо такое неблокирующее, то вызов какого-нибудь sendfile(а еще проще - read из файла) при отсутствии данных в кеше и медленных дисков весь этот event loop остановит.

Вы говорите про блокирующий вызов. Как насчет aio_write ?

anonymous
()
Ответ на: комментарий от anonymous

сервер, обрабатывающий 30-60k коннектов

Можно сделать prefork сервер на чистом perl

да конечно, можно, только работать на такой нагрузке он не будет

впрочем, серьёзным перл-программистам, не способным показать ни один проект со своим участием, но учащих всех, как программировать, эти частности не мешают

Кому ты это рассказываешь?

# ps ax|grep hypnotoad|wc -l 305

Прямо сейчас на одном из серверов 305 процессов hypnotoad (http://search.cpan.org/search?query=hypnotoad&mode=all).

anonymous
()
Ответ на: комментарий от anonymous

ну, и сколько запросов _одновременно_ (не в секунду) обрабатывают эти 305 процессов? 305 или 30500?

у меня и по 2к префорк-серверов бегало, это не аргумент

anonymous
()
Ответ на: комментарий от anonymous

ну, и сколько запросов _одновременно_ (не в секунду) обрабатывают эти 305 процессов? 305 или 30500?

Если речь про одновременное исполнение, то эти аппликейшн сервера не годятся в качестве примера. Под ними исполняется чистый прикладной код и обрабатывает 1 соединение за единицу времени.

Если речь про одновременное исполнение, то нам интереснее будет любой из двух rpc-серверов, каждый из которых принимает и обрабатывает по 1 соединению от 305 потоков. RPC-севера однопоточные, сделаны на anyevent. RPC тестировались на 200 потоках и, по памяти, нагрузка на cpu была незначительной. Но данные у меня не сохранились. Мне самому интересно стало. Могу сделать 200 потоков этих же rpc-серверов (они на anyevent) и на каждой из них послать по 300 соединении с удаленных систем. Этот тест будет достаточным или что-то добавить?

anonymous
()
Ответ на: комментарий от SI

Давай, вылезай из анабиоза. Python 3 полностью юникоидный.

Deleted
()
Ответ на: комментарий от spy

например, наличие fork() в языке - это ужас. потому на windows начинаются жуткие костыли для его эмуляции.

Я тут как раз мимо одной темки проходил. Начиная с 7-рки есть

RtlCreateProcessReflection

Reflect (clone) the process for the dump to minimize the time the process is suspended (Windows 7 and higher only).

Кроме этого ещё есть какая-то NT-specific fork() implementation. Может кому будет полезно.

EvilFox ★★
()
Ответ на: комментарий от anonymous

200 потоков и 30000-60000 потоков — как бы совсем разные порядки

на 30к у тебя префорк-архитектура не справится, таковы реалии. судя по тому, что ты с этим не сталкивался, тебе не приходилось масштабироваться даже на 10k concurrent

anonymous
()
Ответ на: комментарий от anonymous

а. стоп. ты про 200х300. попробуй запустить (даже без лоад-баунсера, хотя в идеале с ним)

вообще, по моему опыту, евент-сервер, отрабатывающий 300 одновременных запросов — непроизводительный и показывает либо сложную логику, либо плохо масштабируемый рантайм

anonymous
()
Ответ на: комментарий от anonymous

200 потоков и 30000-60000 потоков — как бы совсем разные порядки

на 30к у тебя префорк-архитектура не справится, таковы реалии. судя по тому, что ты с этим не сталкивался, тебе не приходилось масштабироваться даже на 10k concurrent

Так конечно. Интересно было бы посмотреть на такие сервера которые тянут по 60к потоков.

а. стоп. ты про 200х300. попробуй запустить (даже без лоад-баунсера, хотя в идеале с ним)

Да, хотел 200x300, но сейчас мощности заняты и похоже что освобождаться не особо собираются. Завтра еще поищу варианты.

вообще, по моему опыту, евент-сервер, отрабатывающий 300 одновременных запросов — непроизводительный и показывает либо сложную логику, либо плохо масштабируемый рантайм

Схему 200х300 можно и перенастроить на 3000х20, если оно себя покажет лучше. Вообще говоря, производительность здесь зависит напрямую от количества событии на один запрос (имеется ввиду 1 клиент = 1 запрос = 1 соединение). Сложность логики - вопрос решаемый и это совсем не проблема, особенно в perl за счет всяких анонимных функции, замыкании и низкоуровневого способа управления вызовами путем косвенной адресации). Можно подробнее насчет рантайма? Не очень понял в чем именно проблемы.

anonymous
()
Ответ на: комментарий от anonymous

Ну поздравляю, сдохнет zsh (ну мало ли), ведь это не язык, а костыли над bash (который костыли над стандартом) - сложно будет переписать. И, субъективно, читается сложнее даже чем bash (у меня только один скрипт был, там какая-то морока с массивами, ну и пара десятков compadd, или как их).

Скрипты для автодополнения я сам не слишком понимаю (в особенности, с _* функциями). Остальное — как напишете. Мороки с массивами больше в bash: «${ARRAY[@]}» (или «${ARRAY

  • }»?) — очень удобный синтаксис. У zsh пока нет конкурентов: в fish слишком много возможностей отсутствует, а остальные и рядом не стояли — кажется, zsh — единственная оболочка с возможностью подсветки и настройкой реакции на любые клавиши на Тьюринг‐полном языке. Есть и другие, но это оболочки языков программирования (вроде bpython), непригодные в качестве системной оболочки.

    Для скрипта: find -maxdepth 1 -name '*.txt' -exec hg mv {} subdir/{} \;, для командной строки: alias n='for n in'; n *.txt; hg mv $n subdir/ (разумеется, нужна только вторая часть, в баше придется добавить {} и ""). А .txt ... .txt - плохо, можно второй раз опечататься, да и длиннее.

    Супер удобно. Особенно первый вариант с учётом того, что мне чаще нужно именно переименовать файл, а не переместить его в подкаталог (с последним отлично справляется и hg mv).

    Действительно.. А вообще вангую студентоту, если ошибся - извиняюсь (впрочем, если не ошибся и обиделись - тоже извиняюсь). А так мне лишь не хватает модификаторов ((.)/(/),(x),(@),(/),(L0) etc), global-alias, =command, while {..;} {} (alias -g W='|while {read l;}') и по-мелочи.

    Про global alias забыл, у меня они тоже есть (в основном используются L='|less' и G='|grep'). Из glob qualifiers почти всегда использую только (/), а он и в bash «есть» (echo **/*/ vs echo **/*).
ZyX
()
Ответ на: комментарий от anonymous

Схему 200х300 можно и перенастроить на 3000х20

3000 воркеров? Они шевелиться не будут

Можно подробнее насчет рантайма?

Легко: пишешь hello world event-сервер на непроизводительном языке программирования — получаешь 100 concurrent, на производительном — 3000 concurrent. Т.е. дело не только в магии event loop, а в том, что для работы с ним не все средства одинаково полезны

anonymous
()
Ответ на: комментарий от anonymous

3000 воркеров? Они шевелиться не будут

Это зависит от мощности сервера и свойств решения которое встречает соединение (считая что к настройке ядра системы претензии нет).

вообще, по моему опыту, евент-сервер, отрабатывающий 300 одновременных запросов — непроизводительный и показывает либо сложную логику, либо плохо масштабируемый рантайм

Можно подробнее насчет рантайма?

Легко: пишешь hello world event-сервер на непроизводительном языке программирования — получаешь 100 concurrent, на производительном — 3000 concurrent. Т.е. дело не только в магии event loop, а в том, что для работы с ним не все средства одинаково полезны

Ты не ответил насчет плохой масштабируемости рантайма. Производительность решения - вещь непостоянная и решение может быть сильно улучшено, это лишь вопрос времени.

anonymous
()
Ответ на: комментарий от anonymous

решение может быть сильно улучшено

вот только если рантайм внизу не позволяет смасштабироваться на нужные величины, придётся всё переписывать без его использования. и аргумент вида «так я же на сишечке постепенно перепишу» — не аргумент, т. к. всё равно речь идёт о переписывании на другом яп ввиду ограничений рантайма яп, выбранного ранее

anonymous
()
Ответ на: комментарий от anonymous

вот только если рантайм внизу не позволяет смасштабироваться на нужные величины, придётся всё переписывать без его использования. и аргумент вида «так я же на сишечке постепенно перепишу» — не аргумент, т. к. всё равно речь идёт о переписывании на другом яп ввиду ограничений рантайма яп, выбранного ранее

Это очень голословное заявление, поэтому местами даже спорное. Ясно что перл отработает медленнее Си поскольку код реализует более сложную логику обработки на исполнителе, но непонятно насколько медленнее. Я тут решил проверить на деле насколько примитивный echo-сервер написанный на perl будет медленнее сервера написанного на Си. Код писал между делом и на коленке, могут быть неточности.

Код сервера на perl

#!/usr/bin/perl

use common::sense;
use Socket qw':DEFAULT IPPROTO_TCP TCP_NODELAY';
use autodie qw'socket setsockopt bind listen';

socket(Server, PF_INET, SOCK_STREAM, IPPROTO_TCP);
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 1);
setsockopt(Server, IPPROTO_TCP, TCP_NODELAY, 1);

my $addr = sockaddr_in(5151, inet_aton('127.0.0.1'));

bind(Server, $addr);
listen(Server, SOMAXCONN);

my $buf;
while(1){
    accept(Client, Server) || die "accept: $!";

    sysread(Client, $buf=undef, 4096);
    syswrite(Client, $buf);
    close(Client);
};

Код сверера на Си

#include <errno.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <string.h>

int Server, Client;
struct sockaddr_in sa;

void perr(char *s){
    perror(s);
    exit(errno);
}

ssize_t c;

int main(int argc, char **argv){
    int v = 1;
    char buf[4096];

    memset(&sa, 0, sizeof(sa));

    sa.sin_family = PF_INET;
    sa.sin_port   = htons(5152);
    if(inet_aton("127.0.0.1", &sa.sin_addr) <= 0){
	perr("inet_aton");
    }

    if( (Server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
	perr("socket");
    }

    if( setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)) < 0){
	perr("SO_REUSEADDR");
    }

    if( setsockopt(Server, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)) < 0){
	perr("TCP_NODELAY");
    }

    if(bind(Server, (const struct sockaddr *)&sa, sizeof(sa)) < 0){
	perr("bind");
    }

    if(listen(Server, SOMAXCONN) < 0){
	perr("listen");
    }

    while(1){
	Client = accept(Server, NULL, NULL);
	c = recv(Client, buf, 4096, 0);
	write(Client, buf, c, 0);
	close(Client);
    }

    return 0;
}

Код benchmark-клиента

#!/usr/bin/perl

use common::sense;
use Benchmark qw':all';
use Socket qw':DEFAULT IPPROTO_TCP TCP_NODELAY';
use autodie qw'socket setsockopt sockaddr_in';

my ($str, $rcv, $addr);

map { $str .= int rand(255) } 0..255;

sub _test{
    for(0..65535){
	socket(Client, PF_INET, SOCK_STREAM, IPPROTO_TCP);

	setsockopt(Client, IPPROTO_TCP, TCP_NODELAY, 1);

        connect(Client, $addr) or die "connect: $!\n";

	syswrite(Client, $str);
        sysread(Client, $rcv, 4096);

	$str eq $rcv or die "Fail\n";

        close Client;
    }
}

sub test1{
    $addr = sockaddr_in(5151, inet_aton('127.0.0.1'));
    _test();
}

sub test2{
    $addr = sockaddr_in(5152, inet_aton('127.0.0.1'));
    _test();
}

cmpthese(10, {
    'perl-server' => 'test1',
    'c-server'	  => 'test2',
});

Си-сервер собирался такой строкой

gcc -O2 -s srv.c -osrv

Версия perl

$ perl --version

This is perl 5, version 20, subversion 0 (v5.20.0) built for x86_64-linux ...

Echo-сервер на Си собирался в том же окружении и тем же компилятором, которым собирался интерпретатор perl

Полученные результаты:

$ perl client.pl

s/iter c-server perl-server

c-server 16.7  — -3%

perl-server 16.1 3% --

anonymous
()
Ответ на: комментарий от anonymous

<продолжение так как комментарии к тестам и коду не влезли>

Полученные результаты:

$ perl client.pl

s/iter c-server perl-server

c-server 16.7 — -3%

perl-server 16.1 3% —

Я на самом деле несколько раз тестировал. Получал и меньшее значение, но думаю среднее значение лежит где-то в районе 3%.

Ясно дело что нельзя говорить о том что любой код на Си будет на 3% быстрее чем на perl, но, с другой стороны, говорить о том что каждые дополнительные N строк/функции будут увиличивать разность в скорости на 3*N %. По крайней мере, у нас появились первые цифры, которые уже как-то можно оценивать. Я думал добавить вычисление regexp-выражении, но тоже нет однозначности в таком тесте. Вообщем, я готов усложнять функционал этих тестов, поэтому предлагайте какой функционал добавлять в тесты.

PS: Обычно, в умных книгах, когда пишут про оптимизацию исполнения, называют цифру в 5% производительности при переходе на С/С++.

anonymous
()
Ответ на: комментарий от fero

Не вздумай! MBR emacs'а на Perl написан. Загружаться перестанет.

Не путаем Perl и Lisp .Из-за чего запомнил Столман написал интерпретатор Lispа а затем после суда и emacs .

maximnik0 ★★
()
Ответ на: комментарий от anonymous

$ perl client.pl

s/iter c-server perl-server

c-server 16.7 — -3%

perl-server 16.1 3% —

Мои результаты тестирования с 50 итерациями в вызове cmpthese:

            s/iter    c-server perl-server
c-server      23.9          --         -1%
perl-server   23.8          1%          --

Три раза пробовал, вместо 3% получал 1%. Тестировал на абсолютно чистом сервере, версия perl 5.20.

anonymous
()
Ответ на: комментарий от anonymous

код на perl разбирается быстрее чем на Си или Java

ХОРОШИЙ код на perl. Впрочем, плохой код на perl сравним с плохим кодом на чём угодно.

Xellos ★★★★★
()
Ответ на: комментарий от anonymous

Я тут решил проверить на деле насколько примитивный echo-сервер написанный на perl будет медленнее сервера написанного на Си. Код писал между делом и на коленке, могут быть неточности.

это однопоточные сервер и клиент. экстраполировать эти данные на многопоточное приложение, мягко говоря, неверно

anonymous
()
Ответ на: комментарий от anonymous

это однопоточные сервер и клиент. экстраполировать эти данные на многопоточное приложение, мягко говоря, неверно

Я и не пытаюсь экстраполировать на многопоточное. Многопоточный сервер уже написал, делаю тесты (очень интересные результаты). В первом примере с однопоточнымы серверами была попытка оценить насколько рантайм perl медленнее себя покажет по сравнению с Си. Чтобы провести такое сравнения я и сделал логику серверов идентичной и постарался сохранить системные вызовы идентичными по коду. Ну клиент в обоих случаях один и тот же, так что он тут не играет роли.

В этом результате кстати следует учитывать что вывод данных выводится от медленного к быстрому. То есть в этом случае сервер на Си проиграл серверу на perl 3%:

$ perl client.pl

             s/iter   c-server    perl-server

c-server       16.7      —            -3%

perl-server    16.1      3%            — 



Но я не сильно рекомендую учитывать это обстоятельство, но дело в том что на некоторых тестах у меня были показатели в 7% выигрыша сервера на perl.

Я и сам не поверил своим глазам, поэтому делал много разных тестов, тестировал на разном железе. В однопоточном и при малом количестве потоков (мультипоточный сейчас тестируется, скоро выложу код и результаты), сервер на perl не отстает от кода на Си, а часто выигрывает несколько %. Может оптимизация какая работает на уровне perl кода, кто-нибудь знает почему так?
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.