gpt4 book ai didi

scope - 当声明符(我的/状态)在 for block 中时会发生什么?

转载 作者:行者123 更新时间:2023-12-04 04:14:35 25 4
gpt4 key购买 nike

以下 block 运行一个循环,将主题分配给变量 $var :

  • 第一个 my $var;在循环之外
  • 第二个my $var;在循环内
  • 最后是 state $var;在循环内
  • my $limit=10_000_000;
    {
    my $var;
    for ^$limit { $var =$_; }
    say now - ENTER now;
    }
    {
    for ^$limit { my $var; $var=$_; }
    say now - ENTER now;
    }
    {
    for ^$limit { state $var; $var=$_; }
    say now - ENTER now;
    }

    每个 block 的示例输出持续时间(秒)如下:
    0.5938845                                                                                                                                 
    1.8251226
    2.60700803

    位于 https://docs.perl6.org/syntax/state 的文档动议 state变量具有与 my 相同的词法范围.从功能上讲,代码块 1 和 block 3 将在对相应循环 block 的多次调用中实现相同的持久存储。

    为什么 state (和内部 my )版本需要更多时间吗?它还在做什么?

    编辑:
    与@HåkonHægland 的评论类似,如果我剪切并粘贴上面的代码以便总共运行每个 block 三次,则 my $var 的时间变化显着。循环外(第一种情况):
    0.600303                                                                                                                                  
    1.7917011
    2.6640811

    1.67793597
    1.79197091
    2.6816156

    1.795679
    1.81233942
    2.77486777

    最佳答案

    短版:在没有任何运行时优化(类型特化、JIT 等)的世界中,时间安排将符合您的期望。这里的时间受到优化器对每个示例的处理程度的影响。

    首先,在没有任何运行时优化的情况下运行代码很有趣。在我当前使用的机器上的(相当慢的)VM 中,坚持 MVM_SPESH_DISABLE=1进入环境导致这些时间:

    13.92366942
    16.235372
    14.4329288

    这些具有某种直观的意义:
  • 在第一种情况下,我们在 block
  • 的外部范围内声明了一个简单的词法变量。
  • 在第二种情况下,我们必须分配一个额外的 Scalar,然后进行垃圾回收。每次循环分配,这占了额外的时间
  • 在第三种情况下,我们使用 state多变的。一个 state变量存储在闭包的代码对象中,然后在进入时复制到调用框架中。这比分配一个新的 Scalar 便宜。每次,但仍然比根本不必执行该操作多一点工作。

  • 接下来,让我们在启用优化器的情况下运行 3 个程序,每个示例都在其自己的独立程序中。
  • 第一个出现在 0.86298831 ,快 16 倍。去优化器!它内联了循环体。
  • 第二个出现在 1.2288566 ,快 13 倍。也不会太破旧。它再次内联了循环体。 (这种情况在 future 也会变得相当便宜,一旦逃逸分析器足够聪明,可以消除 Scalar 分配。)
  • 第三个出现在 2.0695035 ,快 7 倍。这是比较不起眼的(即使仍然是相当大的改进),主要原因是它没有内联循环体。为什么?因为它还不知道如何内联使用状态变量的代码。 (如何查看:在环境中使用 MVM_SPESH_INLINE_LOG=1 运行,其中的输出是:Can NOT inline (1) with bytecode size 78 into (3): cannot inline code that declares a state variable。)

  • 简而言之,这里的主要因素是循环体的内联,以及目前不可能的状态变量。

    目前尚不清楚为什么优化器在外部声明 $var 的情况下表现更差。当这不是程序中的第一个循环时;这感觉更像是一个错误,而不是“此功能尚未优化”的合理案例。在其轻微的防御中,它仍然能够持续提供很大的改进,即使没有达到预期的那么大!

    关于scope - 当声明符(我的/状态)在 for block 中时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55566992/

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