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

发布于 2024-09-16 00:43:14 字数 803 浏览 10 评论 0原文

我想知道,-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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光礼记 2024-09-23 00:43:14

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

  • 无值 (undef)
  • 数字
  • 字符串
  • 引用
  • 列表(由一种或多种前面的类型组成)

您可以使用其中任何一种来创建常量。 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):

  • no value (undef)
  • numbers
  • strings
  • references
  • lists (made up of one or more of the previous types)

You can make a constant out of any of those. Perl 5 also has three containers:

  • Scalar
  • Array
  • Hash

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.

把昨日还给我 2024-09-23 00:43:14

你不能在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文