O=Deparse 如何工作,Perl 是否具有和折叠常量数组?
我想知道,-MO=Deparse
是否向您展示了所有 Perl 优化,以及为什么在 Perl 5.10 中没有折叠这些优化?
$ perl -MO=Deparse -e'[qw/foo bar baz/]->[0]'
['foo', 'bar', 'baz']->[0];
-e syntax OK
IRC 上的一些人认为 O=Deparse
可能没有显示全部内容,但它确实显示了一些常量折叠。
$ perl -MO=Deparse -e'use constant "foo" => "bar"; foo'
use constant ('foo', 'bar');
'???';
-e syntax OK
如果我显式编写常量 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
我能得出的唯一结论是 -MO=Deparse
显示了所有折叠,而常量数组在 Perl 中没有得到优化?是这样吗?有技术原因吗?
I'm wondering, does -MO=Deparse
show you all of the Perl optimizations, and why doesn't this get folded in Perl 5.10?
$ perl -MO=Deparse -e'[qw/foo bar baz/]->[0]'
['foo', 'bar', 'baz']->[0];
-e syntax OK
Some on IRC thought that O=Deparse
might not be showing it all, but it certainly shows some constant folding.
$ perl -MO=Deparse -e'use constant "foo" => "bar"; foo'
use constant ('foo', 'bar');
'???';
-e syntax OK
Same result if I explicitly write the constant sub. While predictable, it is also rather interesting that the documentation in constant.pm
has you create a constant list rather than a constant array. I assume that not just is this not folded like scalar constants but it requires the overhead of creating a new array on every invocation.
$ perl -MO=Deparse -e'use constant foo => qw/foo bar baz/; (foo)[0]'
use constant ('foo', ('foo', 'bar', 'baz'));
(foo)[0];
-e syntax OK
The only conclusion that I can come to is -MO=Deparse
is showing all of the folding, and constant arrays are just not optimized out in Perl? Is this so? Is there a technical reason for it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法创建常量数组,因为数组不是数据。 Perl 5 有五种数据类型(可以存储在变量中的数据):
您可以使用其中任何一种来创建常量。 Perl 5 还具有三种容器:
标量可以保存前四种数据类型中的任何一种,数组和散列可以保存列表。重要的是不要混淆保存数据的东西和数据本身。
至于
B::Deparse
,它会在之后转储optree它是构建的,所以它会显示所有常量折叠的结果。我还没想够,但我没有看到任何明显的原因表明它不能折叠。
You can't create constant arrays because arrays are not data. Perl 5 has five types of data (things that can be stored in variables):
You can make a constant out of any of those. Perl 5 also has three containers:
Scalars can hold any of the first four types of data, arrays and hashes can hold lists. It is important not to confuse things that hold data and the data itself.
As for
B::Deparse
, it dumps the optree after it is built, so it will show the results of all constant folding.I haven't thought about it enough yet, but I do not see any obvious reasons that it couldn't be folded.
你不能在 Perl 中创建常量数组,内部没有任何东西可以指示常量数组或散列,甚至标量。 “使用常量”利用 Perl 的内联子例程的能力,其原型为
()
和简单的代码。您能做的最好的事情就是设置 readonly 标志,但可以在运行时将其关闭。Perl 可以在编译时使用只读标志作为提示来指示该数组确实是只读的,然后使用常量索引内联任何访问。这种启发式方法可能是安全的,因为只读标志不应该是用户可访问的,并且您可能不应该将其关闭。
You can't make a constant array in Perl, there's nothing in the internals to indicate a constant array or hash or even a scalar. "use constant" takes advantage of Perl's ability to inline subroutines with a prototype of
()
and simple code. The best you can do is set the readonly flag, but that can be switched off at runtime.Perl could use the readonly flag at compile time as a hint to indicate that the array really is readonly and then inline any access using a constant index. Such a heuristic would probably be safe as the readonly flag isn't supposed to be user-accessible and you probably shouldn't be flipping it off.