среда, 24 декабря 2014 г.

HTTP content encoding

Решил прикрутить к AnyEvent::HTTP Accept-Encoding и к LWP в response_data handler, но перед этим выяснить какой процент серверов понимает gzip и deflate.

deflate кодирование реализовано в серверах двумя способами и поэтому авторы nginx отказались от его реализации и используют только gzip
(http://sysoev.ru/mod_deflate/readme.html#mehtods).

Под рукой оказался файл с 53587 доменами со следующим распределением по зонам:
  29244 com    1000 de      627 it
   3102 org     935 info    553 ca
   2786 uk      861 nl      504 si
   2734 net     853 au      467 fr
   1315 ru      682 br      368 ua

Для каждого домена запрашивал HTTP содержимое с указанием "Accept-Encoding" в трех различных вариантах: "gzip, deflate" (приоритет gzip), "deflate, gzip" (приоретет deflate) и "deflate". Результаты как закодировал ответ сервер представлены в нижеприведенной таблице (прочерк означает, что сервер вернул не закодированное содержимое):
             | "gzip, deflate" | "deflate, gzip" | "deflate"
 ------------|-----------------|-----------------|----------
 -           |     22888       |     22764       |  50462
 gzip        |     30612       |     30442       |    145
 deflate     |        67       |       361       |   2959
 iso-8859-1  |         1       |         1       |      1
 none        |        16       |        16       |     16
 none;       |         1       |         1       |      1
 UTF-8       |         2       |         2       |      2

Как видим, можно ограничиться поддержкой лишь одного gzip.

Заодно узнал популярность серверов:
                Все зоны | ru зона | ua зона
 ------------------------|---------|--------
 Apache            27327 |     978 |    443 
 nginx              6924 |     922 |    332
 Microsoft-IIS      6886 |     323 |    148
 -                  6116 |     212 |    103

пятница, 13 июня 2014 г.

COW in perl-5.20

В perl-5.20 реализовали механизм копирования при записи (copy-on-write) для строк. Теперь при присвоении одному скаляру значения другого, копирования буфера строки сразу не происходит. Это значительно повышает производительность и снимает необходимость передачи аргументов функций по ссылке (если они не будут изменяться).

Сравним скорость вызова подпрограмм с различными комбинация передачи параметра и возвращения результата для предыдущей версии perl и для версии с COW:
> perlbrew use perl-5.18.2
> perl ref_and_val.pl
                  Rate val -> val   val -> ref   ref -> val   ref -> ref  
val -> val     68213/s           --         -51%         -51%         -97%
val -> ref    138122/s         102%           --          -1%         -93%
ref -> val    139276/s         104%           1%           --         -93%
ref -> ref   2000000/s        2832%        1348%        1336%           --

> perlbrew use perl-5.20.0
> perl ref_and_val.pl
            (warning: too few iterations for a reliable count)
            (warning: too few iterations for a reliable count)
            (warning: too few iterations for a reliable count)
                  Rate ref -> val   val -> val   ref -> ref   val -> ref  
ref -> val   2083333/s           --         -17%         -21%         -29%
val -> val   2500000/s          20%           --          -5%         -15%
ref -> ref   2631579/s          26%           5%           --         -11%
val -> ref   2941176/s          41%          18%          12%           --
Результаты впечатляют, так как длина тестируемой строки 100000 символов!

А теперь возьмем реальное приложение. Оно сетевое, занимается "перекладыванием байтиков" с одного источника в 4 на основе srs32.
Ниже приведены количество запрос в секунду для 3 различных типов запросов в простом и pipeline режимах. Уточнение: сеть не является узким местом.
                 1     2     3
perl-5.14.4   7272  6134  3886
perl-5.18.2   7610  6439  4139
perl-5.20.0   7581  6459  4338

pipeline mode:
perl-5.14.4  21141 13869  5998
perl-5.18.2  21367 14025  6269
perl-5.20.0  21598 14367  6518
Как видим, в реальном приложении выигрыш от COW не заметен.