Я отправляю это как ответ, чтобы забрать из комментариев - хэши против констант:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use Benchmark qw(:all);
use constant ABC => 'DEF';
use constant GHI => 'JKL';
my $ABC = 'DEF';
my $GHI = 'JKL';
my %test_hash = (
ABC => 'DEF',
GHI => 'JKL'
);
sub access_hash {
my $value = $test_hash{ABC};
my $value2 = $test_hash{DEF};
}
sub access_constant {
my $value = ABC;
my $value2 = GHI;
}
sub access_scalar {
my $value = $ABC;
my $value2 = $GHI;
}
my $count = 100_000_000;
cmpthese(
$count,
{ 'hash' => \&access_hash,
'constant' => \&access_constant,
'scalar' => \&access_scalar
}
);
Результаты:
Rate hash scalar constant
hash 9427736/s -- -7% -10%
scalar 10143017/s 8% -- -3%
constant 10492078/s 11% 3% --
Так что вы правы - это быстрее используйте константу. Тем не менее, я бы предложил для операции, которая работает со скоростью 10M/sec, «сохранение» 5% (или даже 10%) просто не стоит взлома, который вам нужно будет сделать.
Но в интересах собственно ответа на вопрос - корень этой проблемы заключается в том, что constant
определяется во время компиляции, где переменные ... нет.
Существует просто отсутствие хеша существующего, когда определено constant
, так что это не сработает. Вы также весьма ограничены тем, что вы действительно можете сделать в блоке BEGIN
. Я думал бы, что вы могли бы , вероятно, запустить процесс 'compile', чтобы превратить ваш файл конфигурации в .pm
, который вы могли бы затем use
.
package import_const;
use constant ABC => 'DEF';
use constant GHI => 'JKL';
Тогда use import_const;
и получить доступ к константы, как import_const::ABC
. (Или используйте Exporter
, чтобы привести их в локальное пространство имен).
sub from_pkg {
my $value = import_const::ABC;
my $value2 = import_const::GHI;
}
Добавим, что в тест синхронизации:
Rate hash scalar imported constant constant
hash 9497578/s -- -6% -9% -9%
scalar 10063399/s 6% -- -4% -4%
imported constant 10473398/s 10% 4% -- -0%
constant 10492078/s 10% 4% 0% --
Я думаю, что я до сих пор утверждают, что выгоды являются маргинальными для усилий.Особенно учитывая use constant will surprise you with it's evil
Там может быть модулем, который может делать то, что вам нужно, хотя:
CPAN modules for defining constants
'использование constants' является Прагма, который вызывается во время компиляции. Ваши переменные существуют только во время выполнения. Вы не можете сделать это за пределами блока «BEGIN» или в eval. Я напишу ответ немного с альтернативами и объяснением. – simbabque
Должен сказать, я никогда не видел большой ценности в «использовании константы» в perl. Кажется, это немного более хрупкое, чем ... ну, просто «нет». – Sobrique
@Sobrique: В моем случае он используется для хранения учетных данных для внешних API. Это самый простой способ сделать их доступными для скриптов, которые в них нуждаются. Какую альтернативу вы бы использовали? – Vince