Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> переменная $_, распределение памяти в Perl 
:(
    Опции темы
AlexPet
Дата 8.7.2008, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 5.12.2007
Где: Брянск

Репутация: 1
Всего: 1



ginnie, полностью с Вами согласен. Просто подумал, а вдруг что-то упустил, какую-нибудь интересную мелочь? smile
PM MAIL ICQ Jabber   Вверх
amg
Дата 9.7.2008, 14:40 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Поигрался с модулем Devel::Size, заодно провел небольшое исследование о памяти, занимаемой различными структурами. Использовал функцию size(), подсчитывающую память, занимаемую самой структурой (в случае нескаляров -- без данных). В модуле есть еще функция total_size() (память для структуры вместе с данными), но она глючит на хэшах. Вот результаты:

undef
12 b

Целые числа
0-4294967296 (2**32) 16 b, далее 20 b

Числа с floating point
20 b

Строки
28 + $n - $n%4 
($n - длина строки)

Массивы
Анонимный массив 
56 + @$aref*4 + $data
(@$aref - число элементов массива, $data - суммарный объем данных, вычисляемый по предыдущим формулам)
Именованный массив
Почему то все сложнее, четкой закономерности я не обнаружил, но приближенно верна формула для анонимного массива
В первом приближении -- данные + 4 байта на каждый элемент

Хеши
Совсем все сложно
(92 + (22+length($key))*$n + 2**(length(sprintf("%b",$n))+2)-32) + $data
Это приближенная формула (в некоторых случаях она не дает точное значение). length($key) - длина ключа хэша (я использовал ключи одинаковой длины, для прикидок можно брать среднюю длину ключа, или максимальную, чтобы с запасом), $n - число элементов хэша (пар ключ-значение), $data - суммарный объем данных (при вычислении нужно помнить, что ключи, как оказалось, если они числа, автоматически превращаются в строки и памяти занимают больше).
В нулевом приближении -- данные + 32 байта на каждый элемент.

Пример того, что хэшами нужно пользоваться с осторожностью
Стандартная задача: организовать быстрый доступ к элементам массива (не по номеру, а по значению). Используют преобразование массива в хэш.
Массив из миллиона целых чисел [1..1000000] занимает в памяти очень умеренные по нынешним временам 20 М.
Хэш {map {$_=>""} 1..1000000}, полученный из этого массива, занимает 410 М. Уже опасно даже по нынешним временам. Использование в качестве значений хэша undef вместо пустой строки "" помогает, но не спасает (экономит лишь 16 М; основное место, 320 М, в этом хэше занимают не данные, а сама структура).

_____________________________
PS Все эти формулы я толком не тестировал, может, они и неправильные. Очевидно, будет зависимость от архитектуры машины и, возможно, от версии Perl (у меня - linux x32, perl 5.8.8)
_____________________________
PPS Что-то я туплю. Как проще вычислить для числа ближайшую к нему (снизу) степень двойки? (вместо того, что у меня  2**(length(sprintf("%b",$n))) )

Это сообщение отредактировал(а) amg - 10.7.2008, 08:28
PM MAIL   Вверх
AlexPet
Дата 9.7.2008, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 5.12.2007
Где: Брянск

Репутация: 1
Всего: 1



Цитата(amg @  9.7.2008,  14:40 Найти цитируемый пост)
PPS Что-то я туплю. Как проще вычислить для числа ближайшую к нему (снизу) степень двойки? (вместо того, что у меня  2**(length(sprintf("%b",$n))) ) 

Если делать по стандарту, то 
Код

int(log($n)/log(2))

Но не думаю, что будет сильный выигрыш во времени smile Даже может наоборот.
PM MAIL ICQ Jabber   Вверх
amg
Дата 9.7.2008, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(AlexPet @  9.7.2008,  14:49 Найти цитируемый пост)
Если делать по стандарту, то ...
Вначале я и использовал выражение с логарифмами, но потом тоже решил, что со sprintf быстрее будет. Но все равно не нравится. Кажется мне, что какой-нибудь pack/unpack здесь будет уместен, но я эти функции плохо знаю.

PM MAIL   Вверх
Jilian
Дата 10.7.2008, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 24.1.2005
Где: Минск

Репутация: нет
Всего: нет



Вы знаете, только что услышала мнение одного специалиста в перл, что изначально переменная $_ занимает все свободную память.
PM MAIL   Вверх
amg
Дата 10.7.2008, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(Jilian @  10.7.2008,  10:36 Найти цитируемый пост)
Вы знаете, только что услышала мнение одного специалиста в перл, что изначально переменная $_ занимает все свободную память.
Может, специалист имел в виду, что переменная может занять все свободную память, и ее (память) не нужно для этого отводить?

PM MAIL   Вверх
Bulat
Дата 10.7.2008, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



Хм.. думаю будет по сабжу. Давно интересовал такой вопрос.

При использовании регулярных выражений, и некоторых функций работающих со строковыми данными, например, 
Код

$text =~ /^(.*?)$/;
print $1;


В данном случае, для того чтобы вытащить из строки некоторую его часть с помощью регулярного выражения, память расходуется ровно, или приблизительно, в два раза больше чем память занимаемая $1. Есс-но я не имею ввиду занимаемую память, в которой хранится весь текст($text). Поэтому при работе с большими текстами, советуют делить строковые данные на более мелкие части, например, построчно.

Все никак не рожу, чтоб поискать и почитать про причины такого поведения.


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
amg
Дата 11.7.2008, 05:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



При этом еще переменныя $+ заполняется тем же самым.
PM MAIL   Вверх
Ramirez
Дата 19.8.2008, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 18.1.2005
Где: Moscow, ExUSSR

Репутация: 4
Всего: 5



Цитата(amg @  9.7.2008,  14:40 Найти цитируемый пост)
Пример того, что хэшами нужно пользоваться с осторожностью

Во многих случаях хеши можно заменить массивами. Можно даже "изобразить" доступ по ключу для удобства:

Код


use constant KEY1 => scalar 0;
use constant KEY2 => scalar 1;

my @arr;

my $arr[KEY1] = 'somevalue';

print $arr[KEY1];



хотя, зачастую вместо констант используется такая конструкция:

Код

sub KEY1 { 0 }

http://www.perl.com/doc/manual/html/pod/pe...stant_Functions

в http://www.perl.com/doc/manual/html/lib/constant.html пишут, что:

In the current implementation, scalar constants are actually inlinable subroutines. As of version 5.004 of Perl, the appropriate scalar constant is inserted directly in place of some subroutine calls, thereby saving the overhead of a subroutine call. See Constant Functions for details about how and when this happens. 

Интересно, как сейчас с этим обстоят дела. Если константа это функция, это ведь оверхед получается неслабый...

попробовал 
Код

guse Devel::Size::Report qw/report_size/;


У меня массив из 1000 элементов занимал 24 килобайта, а хеш - 52 килобайта. Т.е. хеш в 2 раза дороже. 
Если использовать массив с константами в качестве "индексов" то к массиву плюс 20 * 1000 = 20 килобайт займут константы. 
Итого размер массива + константы примерно будет равен хешу, что сведет преимущества к нулю.

Преимущества от массива с константами перед хешем будет если используется одновременно много таких массивов, т.к. константы/индексы будут общие на все массивы. 

Это сообщение отредактировал(а) Ramirez - 19.8.2008, 18:09
PM ICQ   Вверх
sir_nuf_nuf
Дата 19.8.2008, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



Ramirez,  оверхеда как раз не получается, на этапе компиляции
perl делает локальные оптимизации, вычисляя константы..
собственно говоря, если вы напишите что то вроде:

Код

sub some_func {
  return 1 + 2 * sin (0.3)  . "ha ha ha";
}


это будет вычислено 1 раз при компиляции, а результат будет подставлен во все вызовы..


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0804 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.