Недавно я играл с задачей 14 из Euler project
: какое число в диапазоне 1..1_000_000
дает самый длинный последовательность Коллатца?
Мне известно о необходимости memoize, чтобы получить разумное время, и следующий фрагмент кода Python
возвращает ответ относительно быстро, используя эту технику (memoize to dict):
#!/usr/bin/env python
L = 1_000_000
cllens={1:1}
cltz = lambda n: 3*n + 1 if n%2 else n//2
def cllen(n):
if n not in cllens: cllens[n] = cllen(cltz(n)) + 1
return cllens[n]
maxn=1
for i in range(1,L+1):
ln=cllen(i)
if (ln > cllens[maxn]): maxn=i
print(maxn)
(адаптировано из здесь; я предпочитаю эту версию, в которой не используется max
, потому что я мог бы захотеть возиться с ним, чтобы вернуть самые длинные 10 последовательностей и т. д.).
Я попытался перевести это как Raku
, оставаясь как можно семантически близким:
#!/usr/bin/env perl6
use v6;
my $L=1_000_000;
my %cllens = (1 => 1);
sub cltz($n) { ($n %% 2) ?? ($n div 2) !! (3*$n+1) }
sub cllen($n) {
(! %cllens{$n}) && (%cllens{$n} = 1+cllen($n.&cltz));
%cllens{$n};
}
my $maxn=1;
for (1..$L) {
my $ln = cllen($_);
($ln > %cllens{$maxn}) && ($maxn = $_)
}
say $maxn
Вот несколько раз, когда я постоянно их запускаю:
$ time <python script>
837799
real 0m1.244s
user 0m1.179s
sys 0m0.064s
С другой стороны, в Raku
:
$ time <raku script>
837799
real 0m21.828s
user 0m21.677s
sys 0m0.228s
Вопрос(ы)
Я неправильно перевожу их, или разница заключается в непримиримом вопросе запуска виртуальной машины и т. д.?
Есть ли умные настройки/идиомы, которые я могу применить к коду Raku
, чтобы значительно ускорить его?
В сторону
Естественно, речь идет не столько об этой конкретной Euler project
проблеме; В более широком смысле меня интересует, существуют ли какие-либо магические арканы ускорения, подходящие для Raku
, о которых я не знаю.
Inline
. Используйте чужие черты, как если бы они были родными для Раку! Все данные, исключения и т. д. автоматически сортируются. Если вы нажмете на ссылку, вы увидитеInline::Python
, который находится в разработке. Может, попробовать? - person raiph   schedule 16.11.2020