Ответ прост, это не имеет значения. Как отмечали многие, это не будет узким местом вашей программы. Оптимизация, чтобы это произошло даже мгновенно, вряд ли повлияет на вашу производительность. Вы должны сначала зарегистрировать , иначе вы просто угадываете и тратите свое время.
Если мы собираемся тратить на это время, давайте хотя бы сделаем это правильно. Ниже приведен код для создания реалистичного теста. Он на самом деле печатает и отправляет информацию о сравнительном анализе в STDERR. Вы запускаете его как perl benchmark.plx > /dev/null
, чтобы вывод не затоплял ваш экран.
Вот 5 миллионов итераций, пишущих в STDOUT. Используя timethese()
и cmpthese()
, мы получаем все данные для сравнения.
$ perl ~/tmp/bench.plx 5000000 > /dev/null
Benchmark: timing 5000000 iterations of concat, list...
concat: 3 wallclock secs ( 3.84 usr + 0.12 sys = 3.96 CPU) @ 1262626.26/s (n=5000000)
list: 4 wallclock secs ( 3.57 usr + 0.12 sys = 3.69 CPU) @ 1355013.55/s (n=5000000)
Rate concat list
concat 1262626/s -- -7%
list 1355014/s 7% --
А вот 5 миллионов записей во временный файл
$ perl ~/tmp/bench.plx 5000000
Benchmark: timing 5000000 iterations of concat, list...
concat: 6 wallclock secs ( 3.94 usr + 1.05 sys = 4.99 CPU) @ 1002004.01/s (n=5000000)
list: 7 wallclock secs ( 3.64 usr + 1.06 sys = 4.70 CPU) @ 1063829.79/s (n=5000000)
Rate concat list
concat 1002004/s -- -6%
list 1063830/s 6% --
Обратите внимание на дополнительный настенный час и системное время, подчеркивая, как то, что вы печатаете, до имеет такое же значение, как и то, что вы печатаете.
Версия списка примерно на 5% быстрее (обратите внимание, что это противоречит логике Павла, подчеркивающей тщетность попыток просто продумать это). Вы сказали, что делаете десятки тысяч таких? Давайте посмотрим ... 100k занимает 146 мс времени на моем ноутбуке (который имеет дерьмовый ввод / вывод), так что лучшее, что вы можете здесь сделать, это сбрить около 7 мс. Поздравляю. Если вы потратили хотя бы минуту на размышления об этом, вам понадобится 40 000 итераций этого кода, прежде чем вы это сделаете. Это не говоря о альтернативных затратах, в эту минуту вы могли бы оптимизировать что-то гораздо более важное.
Теперь, кто-то скажет: «теперь, когда мы знаем, какой путь быстрее, мы должны написать его быстрым способом и сэкономить это время в каждой программе, которую мы пишем, чтобы сделать все упражнение стоящим!» Нет. Это по-прежнему будет составлять незначительную часть времени выполнения вашей программы, гораздо меньше, чем 5%, которые вы получаете, измеряя один оператор. Во-вторых, подобная логика заставляет вас расставлять приоритеты микрооптимизации над обслуживаемостью.
Да, и отличается в 5.8.8 от 5.10.0.
$ perl5.8.8 ~/tmp/bench.plx 5000000 > /dev/null
Benchmark: timing 5000000 iterations of concat, list...
concat: 3 wallclock secs ( 3.69 usr + 0.04 sys = 3.73 CPU) @ 1340482.57/s (n=5000000)
list: 5 wallclock secs ( 3.97 usr + 0.06 sys = 4.03 CPU) @ 1240694.79/s (n=5000000)
Rate list concat
list 1240695/s -- -7%
concat 1340483/s 8% --
Может даже измениться в зависимости от того, какой уровень ввода / вывода Perl вы используете и какой операционной системы. Так что все упражнение бесполезно.
Микрооптимизация - дурацкая игра. Всегда делайте профиль первым и обращайтесь к оптимизации вашего алгоритма. Devel :: NYTProf - отличный профилировщик.
#!/usr/bin/perl -w
use strict;
use warnings;
use Benchmark qw(timethese cmpthese);
#open my $fh, ">", "/tmp/test.out" or die $!;
#open my $fh, ">", "/dev/null" or die $!;
my $fh = *STDOUT;
my $hash = {
foo => "something and stuff",
bar => "and some other stuff"
};
select *STDERR;
my $r = timethese(shift || -3, {
list => sub {
print $fh $hash->{foo}, "|", $hash->{bar};
},
concat => sub {
print $fh $hash->{foo}. "|". $hash->{bar};
},
});
cmpthese($r);