O = Deparse是如何工作的,Perl是否具有折叠常数数组?

Eva*_*oll 8 perl compiler-optimization perl5.10 constantfolding

我想知道,确实-MO=Deparse向您展示了所有Perl优化,为什么不在Perl 5.10中折叠?

$ perl -MO=Deparse -e'[qw/foo bar baz/]->[0]'
['foo', 'bar', 'baz']->[0];
-e syntax OK
Run Code Online (Sandbox Code Playgroud)

IRC的一些人认为O=Deparse可能没有全部显示,但它确实显示了一些不断折叠.

$ perl -MO=Deparse -e'use constant "foo" => "bar"; foo'
use constant ('foo', 'bar');
'???';
-e syntax OK
Run Code Online (Sandbox Code Playgroud)

如果我明确写出常量sub,结果相同.虽然可预测,但是文档中constant.pm包含的是创建常量列表而不是常量数组也很有趣.我假设这不仅仅是像标量常量那样折叠,而是需要在每次调用时创建新数组的开销.

$ perl -MO=Deparse -e'use constant foo => qw/foo bar baz/; (foo)[0]'
use constant ('foo', ('foo', 'bar', 'baz'));
(foo)[0];
-e syntax OK
Run Code Online (Sandbox Code Playgroud)

我能得出的唯一结论-MO=Deparse是显示所有折叠,而常量数组在Perl中没有优化?是这样吗?它有技术原因吗?

Cha*_*ens 9

您不能创建常量数组,因为数组不是数据.Perl 5有五种类型的数据(可以存储在变量中的东西):

  • 没有价值(undef)
  • 数字
  • 字符串
  • 引用
  • 列表(由一个或多个以前的类型组成)

你可以在其中任何一个中保持不变.Perl 5还有三个容器:

  • 纯量
  • 排列
  • 哈希

标量可以保存前四种类型的数据中的任何一种,数组和散列可以保存列表.重要的是不要混淆包含数据和数据本身的东西.

至于B::Deparse它在构建后转储了optree,因此它将显示所有常量折叠的结果.

我还没有想到它,但我没有看到任何明显的原因,它不能折叠.

  • `strict`编译指示不能减慢运行时间(除非运行时通过字符串`eval`包含新的编译时间).它的所有影响都在编译时.我认为`严格'是在构建optree时运行,而不是之后.你还没有得到关于`strict`的信息.这是Perl 5运行时错误,与`strict`或`warnings`无关.它类似于`perl -e'$ x = $ y = 0; $ X/$ y'`. (2认同)

Sch*_*ern 8

你不能在Perl中创建一个常量数组,内部的任何内容都没有表示常量数组或散列甚至是标量."使用常量"利用了Perl使用原型()和简单代码内联子程序的能力.您可以做的最好的事情是设置readonly标志,但可以在运行时关闭.

Perl可以在编译时使用readonly标志作为提示,指示该数组确实是只读的,然后使用常量索引内联任何访问.这样的启发式可能是安全的,因为readonly标志不应该是用户可访问的,你可能不应该将其翻转掉.