169 похожих чатов

Полный код такой: #!/usr/bin/perl use strict; use warnings; use feature 'say'; use feature qw/switch/; no warnings

qw/deprecated::smartmatch/;

use Benchmark qw(:all);
use Switch '__';

my $x = 5;
my @arr = ('zero', 'one', 'two', 'three');
my %hash = (
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
);

cmpthese(-1, +{
'array lookup' => sub {
my $y = $arr[$x] // 'too many';
},
'hash lookup' => sub {
my $y = $hash{$x} // 'too many';
},
"?:" => sub {
my $y =
!$x ? 'zero'
: $x == 1 ? 'one'
: $x == 2 ? 'two'
: $x == 3 ? 'three'
: 'too many'
;
},

"&& ||" => sub {
my $y =
!$x && 'zero'
|| $x == 1 && 'one'
|| $x == 2 && 'two'
|| $x == 3 && 'three'
|| 'too many'
;
},

"and or" => sub {
my $y =
(!$x and 'zero'
or $x == 1 and 'one'
or $x == 2 and 'two'
or $x == 3 and 'three'
or 'too many'
);
},

"elsif" => sub {
my $y;
if ( !$x ) { $y = 'zero' }
elsif ($x == 1) { $y = 'one' }
elsif ($x == 2) { $y = 'two' }
elsif ($x == 3) { $y = 'three' }
else { $y = 'too many' }
},

"sub return if ..." => sub {
my $y = (sub {
return 'zero' if !$x;
return 'one' if 1 == $x;
return 'two' if 2 == $x;
return 'three' if 3 == $x;
return 'too many';
})->();
},

"given" => sub {
my $y;
given($x) {
$y = 'zero' when !$_;
$y = 'one' when 1;
$y = 'two' when 2;
$y = 'three' when 3;
default { $y = 'too many' }
}
},

"switch" => sub {
my $y;
(sub {
switch($x) {
case !__ { $y = 'zero' }
case 1 { $y = 'one' }
case 2 { $y = 'two' }
case 3 { $y = 'three' }
else { $y = 'too many' }
}
})->();
},

"{}" => sub {
# Тут выражения вычисляются все, а не последовательно,
# поэтому раскрывают частный случай
my $y = +{
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
}->{$x} // 'too many';
},
});

19 ответов

41 просмотр

Если поставить в каждом тесте my $x = int rand 5;, то результаты будут не по одному кейсу...

Vyacheslav-Koval Автор вопроса
Ярослав🧞 Косьмина
Если поставить в каждом тесте my $x = int rand 5;,...

Да, но и точности и смысла в бенчмарке не будет. В одном варианте будет больше вариантов с лучшим случаем - $x == 0 - зашли в первый if и пошли дальше, а в других больше худших случаев - $x > 3.

Vyacheslav Koval
Да, но и точности и смысла в бенчмарке не будет. В...

В cmpthese можно указать количество повторений: 100_000, тогда $x в каждом случае будет от 0 до 4 одинаковое количество раз

Vyacheslav-Koval Автор вопроса
Ярослав🧞 Косьмина
В cmpthese можно указать количество повторений: 10...

Если нужно для всех, то может лучше сделать цикл от 0 до 4?

Vyacheslav Koval
Если нужно для всех, то может лучше сделать цикл о...

Это - тоже частный случай. В реальности цифры ведь будут приходить в разброс. В perl и библиотеке libc, которую он использует для вывода, в драйвере ос, который отвечает за ввод-вывод процессов и в терминале могут быть кеши и различный код с неизвестным поведением, который выполняется разное время. (Тут же ещё say тестируется) Поэтому, если нужно тестировать только условия, то нужно убрать say, но тогда присваивать результат глобальной переменной или оптимизатор вообще может убрать код. Интерпретатор может иметь оптимизацию цикла и условия в последовательном цикле могут работать иначе

Vyacheslav-Koval Автор вопроса
Ярослав🧞 Косьмина
Это - тоже частный случай. В реальности цифры ведь...

В моем примере выше я как раз убрал say и вызов do в придачу.

Vyacheslav-Koval Автор вопроса
Ярослав🧞 Косьмина
Это - тоже частный случай. В реальности цифры ведь...

Если есть оптимизация цикла, то она будет работать для всех случаев.

Ярослав🧞 Косьмина
Если поставить в каждом тесте my $x = int rand 5;,...

Поскольку в этом месте никто не встрял, попробую встрять я ) Есть вполне документированная фича у функции srand, а именно, после вызова: srand число; все последующие вызовы rand будут генерировать одни и те же последовательные значения (для разного "число" будут разные последовательности, разумеется, еще от компа зависит - какие) https://perlbanjo.com/54aaef218a соответственно, и с помощью rand мы можем сгенерить одни и те же тестовые последовательности для каждой функции (тут пример был ошибочный, нужно придумать как именно)

mr bbon
Поскольку в этом месте никто не встрял, попробую в...

Идея хорошая, но в cmpthese - малореализуемая

Ярослав🧞 Косьмина
Идея хорошая, но в cmpthese - малореализуемая

"?:" => sub { state $init = undef; if (!$init) { $init = srand 2; } my $x = int rand 5; say !$x ? 'zero' : $x == 1 ? 'one' : $x == 2 ? 'two' : $x == 3 ? 'three' : 'too many' ; }, "&& ||" => sub { state $init = undef; if (!$init) { $init = srand 2; } my $x = int rand 5; say !$x && 'zero' || $x == 1 && 'one' || $x == 2 && 'two' || $x == 3 && 'three' || 'too many' ; }, # и т.д. так работает, только не забыть в скрипте use v5.10;

mr bbon
"?:" => sub { state $init = undef; ...

Можно короче. state $init; $init//=srand(2); Можно и так state $init=srand(2); Но это багоопасная привычка и так лучше не делать

mr bbon
Поскольку в этом месте никто не встрял, попробую в...

Был такой кейс, когда после fork вызывался rand - и в обоих процессах выдавал одинаковое число. Выход - сначала srand, который в обоих процессах инициирует разные стартовые последовательности.

Андрей aka ti-an
Был такой кейс, когда после fork вызывался rand - ...

В обоих не нужно, достаточно в одном, при этом не важно в каком

Anton Petrusevich
Исправили

Что-то не пойму, где ошибся. А если не ошибся, то почему rand() выдаёт разные числа даже в 5.8 https://perlbanjo.com/d27c0dd6f4

Denis Evdokimov
Что-то не пойму, где ошибся. А если не ошибся, то ...

Я кстати тоже сталкивался, причём под mod_perl, лет десять назад. Так что перл не очень старый должен быть. Но там эта хрень была завязана на внешний модуль какой-то. Надо будет поковыряться в своих архивах

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
1
Он в одиночку это дело запилил или была какая-то команда?
Aquinary
12
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Всем привет, нужна как никогда, нужна помощь с IO в загрузчике. Пишу в code16 после установки сегментных регистров, пишу вывод символа. Пробовал 2 варианта: # 1 mov $0x0E, %a...
Shadow Akira
14
Карта сайта