Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > что быстрее?


Автор: demond 7.11.2008, 19:58
Здравствуйте. Подскажите, кто знает, что будет быстрее:
Код

print "$test0#$test1#$test2#$test3#$test4#$test5#$test6#$test7#$test8#$test9\n";
 
или
Код

print $test0."#".$test1."#".$test2."#".$test3."#".$test4."#".$test5."#".$test6."#".$test7."#".$test8."#".$test9."\n";

или
Код

my $p=join("#",($test0,$test1,$test2,$test3,$test4,$test5,$test6,$test7,$test8,$test9));
print $p."\n";

Почему и как это проверить? а то benchmark одни нули выдает. :-(

Автор: ginnie 7.11.2008, 20:01
demond, быстрее, скорее всего будет вариант

Код

print $test0, '#', $test1, '#', $test2, '#', $test3, '#', $test4, '#', $test5, '#', $test6, '#', $test7, '#', $test8, '#', $test9, $/;

Автор: KSURi 7.11.2008, 20:07
Разница будет настолько микроскопична, что даже не стоит на этом заморачиваться.

Автор: ginnie 7.11.2008, 20:26
Скрипт print_test.pl

Код

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark qw(:all) ;

our ($test0, $test1, $test2, $test3, $test4, $test5, $test6, $test7, $test8, $test9) = ('abcdefgh') x 10;
cmpthese(
    100000, 
    {
        1 => sub {print STDERR  "$test0#$test1#$test2#$test3#$test4#$test5#$test6#$test7#$test8#$test9\n";},
        2 => sub {print STDERR $test0, '#', $test1, '#', $test2, '#', $test3, '#', $test4, '#', $test5, '#', $test6, '#', $test7, '#', $test8, '#', $test9, "\n";},
        3 => sub {my $p=join("#",($test0,$test1,$test2,$test3,$test4,$test5,$test6,$test7,$test8,$test9));
print STDERR $p."\n";},
        4 => sub {print STDERR $test0."#".$test1."#".$test2."#".$test3."#".$test4."#".$test5."#".$test6."#".$test7."#".$test8."#".$test9."\n";},
    }
);


результат perl print_test.pl 2>/dev/null
Код

         Rate    2    1    4    3
2  45552/s   -- -71% -73% -74%
1 156098/s 243%   --  -7% -10%
4 168421/s 270%   8%   --  -3%
3 172973/s 280%  11%   3%   --


Понять проблемы по второму варианту пока не смог.

Автор: demond 7.11.2008, 20:49
действительно странно! самым долгим должен быть 1-й вариант. надо еще потестить. может дело в конкатенации через ","?

Код

      Rate    2    1    3    4
2 153846/s   -- -68% -68% -69%
1 476190/s 210%   --  -0%  -5%
3 476190/s 210%   0%   --  -5%
4 500000/s 225%   5%   5%   --


perl 5.10

Автор: tolkien 11.11.2008, 13:22
Я для себя выбрал делать так 
1 
Код

print $a,"\n";

 т.е выводить по отдельности без склеивания строк. Если включена буферизация, то я думаю этот вариант будет быстрее работать чем.  
2 
Код

print "$a\n"; 

Вот если буферизация выключена, то вариант 1 будет работать медленнее, т.к будет выполнено 2 операции вывода вместо одной. 


И хочу поделиться опытом ).
Как писать быстрые функции с хеш интерфесом func(PARAM1 => VALUE1, PARAM2 =>VALUE2,...)
я сразу после строки
my %args = (PARAM1 => DEFAULT_VALUE1,  PARAM2 => DEFAULT_VALUE2,..., @_);
делаю присваивание отдельным скалярным переменным
my $param1 = $args{PARAM1};
my $param2 = $args{PARAM2};
...
т.к доступ к значению хранящемуся в хэше в 4 раза медленее чем к значению хранящемуся в скаляре. Конечно минус этого что происходит лишнее копирование. Но если значения параметров хеш функции хотя бы 2 раза встречаются в коде, то это уже дает выигрыш в производительности. Кроме того делает код лучше для чтения. И конечно передавать строки нужно всегда только через ссылки. 

Автор: demond 11.11.2008, 13:42
Я где-то прочитал, что вариант:
Код

print "$a\n";

будет медленей, чем:
Код

print $a."\n";

потому что в 1-м варианте perl'лу приходится раскрывать кавычки для получения значения $a. А это очень ёмкая операция. Вот хотелось бы проверить... Только видимо в при нынешней производительности компьютеров, разницу не заметить!

Автор: ginnie 11.11.2008, 13:59
tolkien, спасибо за подсказку с буферизацией!

Изменение буферизации STDERR при помощи

Код

use IO::Handle;

autoflush STDERR 1;


вообще ни на что не влияет в случае перенаправления STDERR в /dev/null.

А вот с выводом в файл цифры изменились. При включенной буферизации

Код

use IO::Handle;
open FILE, '>', 'output.log' or die "can't open file: $!";
autoflush FILE 0;


      Rate    2    4    1    3
2 162025/s   -- -11% -11% -13%
4 182857/s  13%   --   0%  -1%
1 182857/s  13%   0%   --  -1%
3 185507/s  14%   1%   1%   --


при выключенной

Код

autoflush FILE 1;


     Rate    3    4    1    2
3 53556/s   --  -0%  -6% -10%
4 53782/s   0%   --  -5%  -9%
1 56889/s   6%   6%   --  -4%
2 59259/s  11%  10%   4%   --


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)