2010-08-24 6 views
8

Мне интересно, -MO=Deparse покажет вам все оптимизации Perl, и почему это не складывается в Perl 5.10?Как работает O = Deparse, а Perl имеет и складывает постоянные массивы?

$ 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? Это так? Есть ли для этого техническая причина?

+1

Я все еще смущен, почему я забираю это для этого? Кто-то бросит мне линию. Это потому, что вопрос слишком эзотеричен? Вы считаете, что это повлечет за собой большую работу за любую прибыль? Я просто спрашивал, можно ли это сделать, и почему это не сделано. [Главный ответ] (http://stackoverflow.com/questions/3561210/how-does-odeparse-work-and-does-perl-have-and-fold-constant-arrays/3561323#3561323), похоже, проходит те же вопросы, о которых я спрашиваю. (1) Предположим, что это невозможно по техническим причинам (2), тогда предположите, что это просто не сделано, (3) затем предположите, что это не сделано, потому что это не имеет большого значения. –

ответ

9

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

  • никакой ценности (UNDEF)
  • номера
  • строки
  • ссылки
  • списки (составленные из одного или больше из предыдущих типов)

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

  • Скалярное
  • массива
  • Hash

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

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

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

+1

Не могли бы вы объяснить '-MO = Deparse -e'use strict; print {} -> [1] 'vs' use strict; print {} -> [1] '. В какой-то момент, строгий знает, что вы пытаетесь получить недопустимую ссылку для N-го элемента (то есть, что '{}' является хэш-ссылкой). Я знаю, что мы говорим пословично, что государство, строящееся, работает во время компиляции. Как строго знать, что это за ссылка? Не могли бы вы объяснить немного больше в этом направлении? –

+1

@Evan Carroll Строгая прагма не понимает этого, она заботится только об объявлении переменных ('' vars "'), запрещении символических ссылок ('" refs ") и запрещении большинства строчек гоблинов (' "subs"). Разновидности '->' оператора во время выполнения, поэтому до этого мы не получаем ошибку. Если мы сделаем '->' постоянную фальцовку, мы, вероятно, поймаем эту ошибку во время компиляции. –

+0

Правило большого пальца всегда заключалось в том, что 'strict' не замедляет время выполнения. Вещи, которые сделали это, были зарезервированы для 'warnings.pm'. Настолько строгий переход через op-tree во время выполнения во время BEGIN {} и выброс исключения, или строгий утверждает, что reftype действителен при стоимости скорости во время выполнения? - Или я все еще не понимаю. –

8

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

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

+1

.. и если вы это сделаете, вы заслуживаете того, что получаете :) – Ether

 Смежные вопросы

  • Нет связанных вопросов^_^