How does O=Deparse work, and does Perl have and fold constant arrays?

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?

8
задан DaveInCaz 20 August 2018 в 17:52
поделиться

2 ответа

Вы не можете создать постоянный массив в Perl, во внутреннем устройстве нет ничего, что указывало бы на постоянный массив, хэш или даже скаляр. «использовать константу» использует возможность Perl встраивать подпрограммы с прототипом () и простым кодом. Лучшее, что вы можете сделать, - это установить флаг только для чтения , но его можно отключить во время выполнения.

Perl мог использовать флаг readonly во время компиляции в качестве подсказки, чтобы указать, что массив действительно доступен только для чтения, а затем встроить любой доступ с использованием постоянного индекса. Такая эвристика, вероятно, будет безопасной, поскольку флаг readonly не должен быть доступен для пользователя, и вам, вероятно, не следует его отключать.

8
ответ дан 5 December 2019 в 10:00
поделиться

Вы не можете создавать массивы констант, потому что массивы не являются данными. Perl 5 имеет пять типов данных (вещи, которые могут храниться в переменных):

  • без значения (undef)
  • числа
  • строки
  • ссылки
  • списки (состоящие из одного или нескольких предыдущие типы)

Вы можете сделать константу из любого из них. В Perl 5 также есть три контейнера:

  • Скаляр
  • Массив
  • Хеш

Скаляры могут содержать любой из первых четырех типов данных, массивы и хэши могут содержать списки. Важно не путать то, что содержит данные, и сами данные.

Что касается B::Deparse, он выгружает оптодерево после его построения, поэтому он покажет результаты всех сворачиваний констант.

Я еще недостаточно об этом думал, но не вижу явных причин, по которым его нельзя было бы свернуть.

9
ответ дан 5 December 2019 в 10:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: