пятница, 29 января 2010 г.

Инструменты разработчика: Devel::TraceUse


Модуль позволяет посмотреть(в виде дерева) какие модули подключает ваша программа. 
Это бывает может быть полезным в разных случаях. Например,  когда  программа сразу после компиляции начинает занимать слишком много памяти...  или бывает непонятно какой из бекендов подключает некий модуль(например JSON)... или просто необходимо собрать список зависимостей  ...  В общем - вариантов может быть масса.
В любом случае попробуйте запустить программу вот так: perl -MDevel::TraceUse myprog.pl, возможно будете удивлены.

Пример вывода:
perl -MDevel::TraceUse -MFindBin -e ''
Modules used from -e:
  FindBin, line 0 (4.8e-05)
    Carp, line 95 (3.9e-05)
    Cwd, line 98 (4.1e-05)
      XSLoader, line 247 (5.3e-05)
    File::Basename, line 99 (5.6e-05)
      re, line 44 (3.8e-05)
    File::Spec, line 100 (4e-05)
      File::Spec::Unix, line 22 (3.6e-05)

среда, 27 января 2010 г.

Движки сериализации: кто быстрее?

Сегодня наткнулся на модуль Benchmark::Serialize, который тестирует разные движки сериализации(
тестируется сериализация, десериализация и размер сериализированных данных).

У меня в системы оказались следующие движки: Data::Dumper 2.124, JSON::PP 2.27000 JSON::XS 2.27, Storable 2.20, XML::Simple 2.18. 

И я был очень и очень удивлен результатом. Первое место по всем показателям достается модулю JSON::XS, при десериализации он быстрее Storable на 30%, а при сериализации в целых 6 (!!!) раз. Размер данных тоже минимальный.

Привожу результаты (исходник бенчмарка в атаче)
               Size     Deflate    Inflate
JSON::XS       376     313980/s   139750/s   
JSON::PP       376       5307/s     1778/s    
Storable       382      46848/s   109720/s    
XML::Simple    502       4912/s     1249/s 
Data::Dumper   1058     15486/s    18719/s

вторник, 26 января 2010 г.

Генерация произносимых паролей

Возникла задача добавления большого списка новых пользователей в систему, притом пароль может устанавливать и менять только администратор. Поскольку лично у каждого пользователя просить ввести пароль не представлялось возможным, то необходимо было сразу сгенерировать удобные для пользователей пароли.

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

Был выбран модуль Text::Password::Pronounceable, результатом работы которого я остался очень доволен.
Модуль простейший, и вся возможности помещаются в два следующих примера генерации произносимого пароля длиной 6-10 символов
пример 1:
Text::Password::Pronounceable->generate(6, 10); 
пример 2:
my $pp = Text::Password::Pronounceable->new(6, 10);  
$pp->generate

Примеры сгенерированных  паролей:
theoro ortofi nditost coftodt thagorth taprnthi ingingr linesror destro icerarado

ЗЫ:  Мне всегда нравились каптчи(CAPTCHA) гугла тем, что они читабельны и этот модуль можно использовать также для генерации текста "вменяемых" каптч.
ЗЫ2: Для генерации более надежных паролей можно использовать Text::Password::Pronounceable::Harden

понедельник, 25 января 2010 г.

Рекурсивное копирование сложных структур данных


Модуль Storable
Классический вариант - это использования функции dclone со стандартного модуля Storable, который предзначен для сериализации данных, и невероятно быстрый. Реализован на 'C' с низкоуровневыми оптимизациями, работающими с внутренней реализацией Perl( инкапсуляция отдданна в жертву в обмен на скорость)
Функция  dclone на самом деле сначала просто сериализирует в память данные, а потом десериализирует в новую структуру( dclone(.) = thaw(freeze(.)) ).
В документации по модулю Storable мы можем найти следующую информацию: 
"There is a Clone module available on CPAN which implements deep cloning natively, i.e. without freezing to memory and thawing the result.  It is aimed to replace Storable's dclone() some day.  However, it does not currently support Storable hooks to redefine the way deep cloning is performed."

Модуль Clone
Модуль Clone позиционирует себя как более производительное решение для клонирования сложных структур данных чем Storable, что прямо написанов документации "For a slower, but more flexible solution see Storable's dclone()."

Результат тестирования(бенчмарк приатачен)
Модуль clone имеет преимущество на простых структурах данных(с минимальным количеством элементов), на сложных структурах - он проигрывает. 
Уже массив с 15 элементов({foo=>'bar', bar=>'foo' })  копируется практически с одинаковой скоростью. При увеличение количества элементов Clone начинает проигрывать. 

                    Rate storable_simple    clone_simple
storable_simple  59644/s              --            -82%
clone_simple    331579/s            456%              --

                     Rate storable_standart    clone_standart
storable_standart 30914/s                --               -3%
clone_standart    31870/s                3%                --

                   Rate    clone_complex storable_complex
clone_complex    3543/s               --             -47%
storable_complex 6719/s              90%               --

Выводы
Практически всегда стандартный модуль Storable явлеется более удачным решением для клонирования структур.

Использование Clone может быть оправдано только в очень ограниченных случаях и при соблюдение следующих условий: 
  1. Копируются очень простые структуры данных 
  2. Эти структуры не являются частью одной сложной структуры( если их много, то скорее всего они в массиве, тогда имеет смысл скопировать весь массив при помощи Storable и это будет однозначно быстрее чем копировать поэлементно или весь массив сразу при помои Clone
  3. Время их копирования является узким местом при выполнении программы.