pri*_*tor 7 performance primes generator raku
我想在学习 Raku 的同时对 Python 和 Raku 进行一些比较。
\n本来我想要一个更大的脚本,但由于差异已经很大,我现在就寻求指导。
\n我尝试忠实地翻译这个 Python 脚本,同时应用不应该损害性能的 Raku 知识:
\nfrom collections import deque\nfrom itertools import count, islice\n\n\ndef primes_wheel():\n yield 2\n composites = {}\n for candidate in count(3, step=2):\n prime = composites.pop(candidate, 0)\n if prime:\n while True:\n candidate += prime + prime\n if candidate not in composites:\n composites[candidate] = prime\n break\n else:\n composites[candidate * candidate] = candidate\n yield candidate\n\n\ndef last(itr):\n return deque(itr, 1).pop()\n\n\nLENGTH = 99999\n\nprint(last(islice(primes_wheel(), 0, LENGTH)))\nRun Code Online (Sandbox Code Playgroud)\n我到达了这个:
\nsub primes_wheel {\n my %composite;\n\n gather {\n take 2;\n for 3,5\xe2\x80\xa6* -> $candidate is copy {\n my $prime = %composite{$candidate}:delete;\n if $prime.defined {\n loop {\n $candidate += $prime + $prime;\n if not %composite{$candidate}:exists {\n %composite{$candidate} = $prime;\n last;\n }\n }\n }\n else {\n %composite{$candidate * $candidate} = $candidate;\n take $candidate;\n }\n }\n }\n}\n\nconstant LENGTH = 99999;\n\nsay primes_wheel[LENGTH - 1];\nRun Code Online (Sandbox Code Playgroud)\n结果确实对 Raku 不利(-OO对 Python 来说没有太大区别,但是--optimize=3使 Raku 变慢):
% hyperfine \'raku primes.raku\' \'python -OO primes.py\'\nBenchmark 1: raku primes.raku\n Time (mean \xc2\xb1 \xcf\x83): 4.953 s \xc2\xb1 0.050 s [User: 4.986 s, System: 0.040 s]\n Range (min \xe2\x80\xa6 max): 4.899 s \xe2\x80\xa6 5.036 s 10 runs\n\nBenchmark 2: python -OO primes.py\n Time (mean \xc2\xb1 \xcf\x83): 291.3 ms \xc2\xb1 13.8 ms [User: 125.2 ms, System: 15.2 ms]\n Range (min \xe2\x80\xa6 max): 266.4 ms \xe2\x80\xa6 315.9 ms 10 runs\n\nSummary\n python -OO primes.py ran\n 17.01 \xc2\xb1 0.82 times faster than raku primes.raku\nRun Code Online (Sandbox Code Playgroud)\n我是否错过了什么或没有以正确的方式使用东西?我希望 Raku 能赶上。我对性能改进和 Rakuisms 都感兴趣。
\n这不是翻译问题:
\n\n\n[\xe2\x80\xa6] 标签中有很多问题要求将 [\xe2\x80\xa6] 代码转换为 [\xe2\x80\xa6]
\n
我自己进行了转换,这很有趣!在这里我问为什么我的结果如此慢(即我如何才能更快地得到它)以及我是否使用正确的方式构建(即导致速度减慢的东西)。
\n我还说过我愿意听到 Rakuisms 来改进它,这不是代码翻译。
\n@Karl Knechtel:我什至可以完全省略 Python 部分,就好像不是翻译一样。这将是同样的问题,也许那时你就会看到它。但我决定保留它,以便答案更接近它。这也是为什么我不接受伊丽莎白的回答,尽管它表明了你应该做什么对生产代码做什么。我有一种感觉,我的 Raku 做错了什么\xe2\x80\x94 至少我希望如此。我希望得到一个答案来发现这一点并让我更深入地理解。SO是关于学习,对吗?
\n话虽如此,“不清楚你要问什么”或链接中的 \xe2\x80\x9cneeds 调试详细信息\xe2\x80\x9d均不适用于此处,恕我直言。
\n在我看来,您应该利用编程语言的优势,而不是试图模仿其他语言的方法。在这种情况下:
constant LENGTH = 99999;
my @primes = (^Inf).grep(*.is-prime);
say @primes[LENGTH - 1];
Run Code Online (Sandbox Code Playgroud)
或者,如果您对两者之间的值并不真正感兴趣:
say (^Inf).grep(*.is-prime).skip(LENGTH - 1).head;
Run Code Online (Sandbox Code Playgroud)
在我的 M1 MacMini 上运行大约需要 0.56 秒。然而,这种管道方法允许使用多个 CPU 进行超级操作:
say (^Inf).hyper(batch => 2048).grep(*.is-prime).skip(99998).head;
Run Code Online (Sandbox Code Playgroud)
这对我来说大约需要 0.24 秒。减去 0.11 的启动开销,速度大约是原来的 3.5 倍。这对于 4 核机器来说还算不错。
| 归档时间: |
|
| 查看次数: |
279 次 |
| 最近记录: |