GoDleSS
Сообщений: 35
Оценки: 0
Присоединился: 2007-02-27 02:47:18.046666
|
Последнее время наталкиваюсь на тот факт, что люди, которым помогаю с перл, практически 100% не знают одной интересной мелочи. По сему решил, что и здесь может быть кому-либо полезно. "Фича" заключается в том, что интерпритатор не убивает локальные переменные после выхода из блока, в котором они определены(для понимания остановимся на подпрограмме sub … { … } ), лишь изменяет содержимое с последующими вызовами. Очистка памяти возникает лишь когда не будет более ссылок на подпрограмму, либо будет вызвана функция exit. Пусть у нас есть подпрограмма, которая генерирует или получает большую структуру данных. Допустим, что вся обработка данных, выдаваемых этой подпрограммой будет произведена до следующего вызова функции. В таком случае при реализации вида my @array=funcName([params]) произойдет дублирование памяти и если мы имеем значительный размер структуры данных это приведет практически к удвоению требуемой оперативной памяти. Что делать? Использовать ссылки + очищать стуктуру в начале подпрограммы, если данные предыдущего вызова не нужны! Пример:
#!/usr/bin/perl
$|=1;
my $link=longArray(1024, 1024*1024);
print ">> $link->[0]\n";
sleep(10);
sub longArray {
my @array=(); # Инициируем локальный для блока массив и сразу очищаем его
my ($strLen, $arrSize) = (shift, shift);
# Заполняем массив
while ($arrSize>=0) {
$array[--$arrSize]=chr(int(rand(255.999))) x $strLen;
}
return \@array; # Возвращаем ссылку на массив, а не саму структуру
}
вместо
#!/usr/bin/perl
$|=1;
my @arr=longArray(1024, 1024*1024);
print ">> $arr[0]\n";
sleep(10);
sub longArray {
my @array=();
my ($strLen, $arrSize) = (shift, shift);
while ($arrSize>=0) {
$array[--$arrSize]=chr(int(rand(255.999))) x $strLen;
}
return @array;
}
С уважением, CheRt[aka_GoDleSS]
|