Могу ли я инициализировать массив с заданным размером в Perl? - PullRequest
19 голосов
/ 20 января 2011

В моем коде есть раздел, в котором я знаю, что мне понадобится массив, и я точно знаю, сколько элементов потребуется в этом массиве.Этот раздел кода будет повторяться много раз, поэтому я мог бы получить очень большую экономию времени, сначала инициализировав этот массив до размера, который, как я знаю, ему понадобится, а затем заполнив его, а не просто вставляя элементы (нажатие будет On) в отличие от заполнения уже созданных пробелов, что будет O (1)).

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

my @array; $array[49] =0;

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

Ответы [ 6 ]

14 голосов
/ 20 января 2011

Если честно, ваш путь в порядке, так как явно изменяется размер массива: $#array = 49;;

12 голосов
/ 20 января 2011
  1. Первое правило Клуба оптимизации - вы не оптимизируете.
  2. Второе правило Клуба оптимизации - вы не оптимизируете без измерения.

ИзмерениеИзмерить, измерить, прежде чем идти и предположить, что вы можете сделать это быстрее, обманув Perl.Perl занимается оптимизацией общего использования гораздо дольше, чем вы.Доверься этому.

6 голосов
/ 20 января 2011

Всякий раз, когда вы думаете об оптимизации этого типа, сделайте профилирование! Результат может быть не тем, что вы ожидаете. Например, я использовал следующий быстрый скрипт, чтобы проверить вашу теорию о том, что предварительное выделение массива происходит быстрее:

for ( my $loops = 0; $loops < 100000; $loops++ )
{
    my @arr;

    for ( my $foo = 0; $foo < 50; $foo++ ) {
        push @arr, 'bar';
    }
}

Это заняло 2,13 секунды.

for ( my $loops = 0; $loops < 100000; $loops++ )
{
    my @arr;
    $arr[49] = 0;

    for ( my $foo = 0; $foo < 50; $foo++ ) {
        $arr[$foo] = 'bar';
    }
}

Это заняло 2,16 секунды (оба теста я запускал несколько раз). Таким образом, на самом деле получается быстрее , чтобы позволить perl обрабатывать выделение массива при необходимости.

Обновление

После внесения изменений, предложенных ysth, числа становятся более понятными: 2,27 секунды для метода «push» и 2,21 для предварительного распределения. Тем не менее, я бы задал вопрос, действительно ли такая оптимизация сэкономит время (разница составляла всего 0,06 секунды после 100 000 итераций).

2 голосов
/ 02 августа 2012

Вместо определенного значения используйте undef

my @array;
$array[49] = undef;
2 голосов
/ 20 января 2011

Ваш путь великолепен, как и у ДВК.Способ сделать это в одной команде может быть:

@array = (0 .. 49);

Но я не уверен, что это более элегантно, поскольку он присваивает значение от 1 до 49 каждому элементу, но, вероятно, более интуитивнопонять программиста не очень в синтаксис Perl.

1 голос
/ 04 июля 2014

Предварительное выделение может не сильно помочь со скоростью, но может помочь с возвратом памяти в систему, если выделенные фрагменты достаточно велики

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...