Иногда требуется выяснить как быстро работает тот или иной фрагмент кода на perl. Для этого можно использовать perl модуль Benchmark, входящий в стандартную поставку perl.
Задача. Как оптимальнее организовать перебор элементов хеша, например просуммировать значения всех ключей. В полном соответствии с принципом TIMTOWTDI существует несколько вариантов решения задачи:
Вариант №1. Использование цикла «foreach ( values ... )».
sub hash_values_sum_1(%) { my %hash = @_; my $sum = 0; $sum += $_ foreach values %hash; return $sum; }
Вариант №2. Использование конструкции«map ... values ... ».
sub hash_values_sum_2(%) { my %hash = @_; my $sum = 0; map { $sum += $_ } values %hash; return $sum; }
Вариант №3. Использование цикла «while ( ... each ... )».
sub hash_values_sum_3(%) { my %hash = @_; my $sum = 0; $sum += $_ while (undef, $_) = each %hash; return $sum; }
Для проверки проверки напишем небольшой тестовый скрипт:
#!/usr/bin/perl -w use strict; use Benchmark qw/ :all /; my %hash = map { rand, rand } ( 1 .. 1000 ); cmpthese( 5_000_000 , { var1 => 'my $sum = 0; $sum += $_ foreach values %hash', var2 => 'my $sum = 0; map { $sum += $_ } values %hash;', var3 => 'my $sum = 0; $sum += $_ while (undef, $_) = each %hash;', } );
Проверяем производительность трех вариантов решения задачи. Для этого используем тестовый хеш, содержащий 1000 случайных ключей со случайными значениями. Для получения усредненных результатов, каждый из вариантов запускается по 5 миллионов раз. Результаты работы скрипта:
Rate variant_1 variant_3 variant_2 var1 946970/s -- -48% -73% var3 1838235/s 94% -- -48% var2 3546099/s 274% 93% --
По таблице результатов видно, что:
- Вариант №3 работает почти в 2 раза быстрее, чем вариант №1.
- Вариант №2 работает почти в 2 раза быстрее, чем вариант №3.
В данном конкретном случае вариант №2 является однозначным победителем. Его использование более предпочтительно.
Комментариев нет:
Отправить комментарий