$i { my $result = ($i ** 2).Str;-6ren">
gpt4 book ai didi

concurrency - Perl 6 中是否有快速并行 "for"循环?

转载 作者:行者123 更新时间:2023-12-04 17:31:04 26 4
gpt4 key购买 nike

给定一些代码对从 1 到 500000 的每个数字进行一些数学/转换,我们有选项:

  • 简单的 for 循环:for ^500000 -> $i { my $result = ($i ** 2).Str; } .在我不科学的基准测试中,这需要 2.8 秒。
  • 最规范的并行版本在 Promise 中完成每一项工作,然后等待结果。 await do for ^500000 -> $i { start { my $result = ($i ** 2).Str; } }需要 19 秒。这很慢!创建一个新的 promise 必须有太多的开销,对于这样一个简单的计算来说是值得的。
  • 使用并行 map操作相当快。在 2.0 秒时,操作似乎几乎不足以利用并行化:(^500000).race.map: -> $i { my $result = ($i ** 2).Str; }

  • 第三种选择似乎是最好的。不幸的是,它读起来像一个黑客。我们不应该写 map在 sink 上下文中进行迭代的代码,因为在源中读取“map”的其他人可能认为目的是构建一个列表,这根本不是我们的意图。使用沟通不畅 map这边走。

    是否有任何规范的快速方法来使用 Perl 6 的内置并发?如果 super 运算符可以接受块而不是仅接受函数,则它是完美的:
    (^500000)».(-> $i { my $result = ($i ** 2).Str; }) # No such method 'CALL-ME' for invocant of type 'Int'

    最佳答案

    如果你想与 super 或种族操作一起使用,你必须拼写它 hyper for @blah.hyper(:batch(10_000))race for @blah.race(:batch(10_000)) .或不带参数:hyper for @blah , race for @blah .

    之所以决定这样做,是因为您可能有类似 for some-operation() { some-non-threadsafe-code } 的代码。哪里some-operation是图书馆或其他东西的一部分。现在你不能再知道 for 循环中是否可以包含线程不安全的代码,即使你知道库没有返回 HyperSeq在那个时候,如果图书馆作者想出了这个好主意来制作 some-operation 会怎样?通过hypering更快吗?

    这就是为什么在代码所在的地方需要“并行运行这个 for 循环是安全的”的能指,而不仅仅是在创建序列的地方。

    关于concurrency - Perl 6 中是否有快速并行 "for"循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47301334/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com