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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> XML::Libxml минимизация расхода памяти 
:(
    Опции темы
shamber
Дата 19.8.2009, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Здравствуйте всем!!!


есть файлик Excel xml размером ~ 6мб.
я его парсю
Код

$doc = $parser->parse_fh($fh);

получается что памяти выделилось допустим 30 мб.
Дальше мне нужно пройтись по всем строкам в файлике за это отвечает тег Row
если сделать так
Код

my @list = $doc->getElementsByTagName("Row");

то выделиться еще около 25 мб. Итого 55 метров.
А хочется не выделять дополнительные 25 метров
А можно ли как-то обойти их по одному, что то типа :
findnode("Row")
nextnode()
?
Точнее мне кажется что можно, но я никак не могу понять как smile
PM MAIL Jabber   Вверх
ginnie
Дата 19.8.2009, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



shamber, может использовать SAX-парсер (например, XML::Twig)?


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
shamber
Дата 19.8.2009, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



спасибо, буду пробовать
PM MAIL Jabber   Вверх
KSURi
Дата 19.8.2009, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

for my $node ($xml->findnodes('//Row')) {
  # ...
}

?

Добавлено @ 14:22
Хотя нет, не то. Наверное все-таки надо SAX-парсер использовать.
Но на всякий случай померяйте вариант с использованием XML::LibXML::NodeList.

Это сообщение отредактировал(а) KSURi - 19.8.2009, 14:28


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
shamber
Дата 19.8.2009, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Вообщем глянул внимательно, понял что приврал smile
6 мб в Dom занимает 70 мб smile
Код

my @list = $doc->getElementsByTagName("Row");

прибавляет 1,5 мб.

А в SAX(XML::Twig) как перейти к следующему элементу?
т.е.
first_child нашел,  а следующий?


Это сообщение отредактировал(а) shamber - 19.8.2009, 14:59
PM MAIL Jabber   Вверх
ginnie
Дата 19.8.2009, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Цитата(shamber @  19.8.2009,  14:52 Найти цитируемый пост)
А в SAX(XML::Twig) как перейти к следующему элементу?

Предположу, что next_sibling. Либо можно children использовать, чтобы получить список.



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
shamber
Дата 20.8.2009, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Эх, Twig тормозит smile
PM MAIL Jabber   Вверх
shamber
Дата 20.8.2009, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Чего-то не понимаю, подскажите где ошибка.
делаю так

Код

my @twig_options = (keep_encoding => 1, TwigRoots=> {Row=>\&row},TwigPrintOutsideRoots => 0);
my $twig = XML::Twig->new(@twig_options);
$twig->parsefile($file);

sub row{
    # let's use the attribute nb as a prefix to the title
    my @title= $_[1]->children( 'Cell'); # find the title
    $str = $title[0]->text;
    undef (@title);
    
    $_[0]->purge;            # outputs the section and frees memory
 }

А расход памяти увеличивается.
PM MAIL Jabber   Вверх
ginnie
Дата 20.8.2009, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



shamber, вроде все правильно делаешь. Насколько сильный расход памяти?


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
shamber
Дата 20.8.2009, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



ginnie, он конечно же меньше чем XML::LibXML.
Но для файла 6 мб, в начале старта скрипта памяти выделяется 9 мб. под конец работы уже 25 мб.
Но не понятно мне почему она во время работы все время увеличивается.

Добавлено через 44 секунды
мне казалось что после purge память должна освобождаться
PM MAIL Jabber   Вверх
ginnie
Дата 20.8.2009, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



shamber, памяти должно использоваться сильно меньше чем в XML::LibXML, т.к. файл читается фрагментами. Надо несколько вызовов row() посмотреть и определить, когда память расходуется.
P.S. Я использовал XML::Twig для обработки xml-файла более 60 Мб, только особого внимания на расход памяти не обращал, т.к. для меня оно значения особого не имело.

Это сообщение отредактировал(а) ginnie - 20.8.2009, 11:10


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
shamber
Дата 20.8.2009, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Код

#!/usr/bin/perl -w
use XML::Twig;
use Win32::API;
use IO::File;


my $start_usage = win32_size_check();

my $file = 'рц.xls';
my $LOG;
$LOG = IO::File->new();
$LOG->open("> "."memory.log");
my @twig_options = (keep_encoding => 1, TwigRoots=> {Row=>\&row},TwigPrintOutsideRoots => 0);
my $twig = XML::Twig->new(@twig_options);
$LOG->print('start ' , $start_usage,"\n");
$twig->parsefile($file);
exit;


sub row{
    $LOG->print('################# ', "\n");
    $LOG->print('in row: ', win32_size_check() - $start_usage, "\t");
    # let's use the attribute nb as a prefix to the title
    my @title= $_[1]->children( 'Cell'); # find the title
    $LOG->print('after children: ', win32_size_check() - $start_usage, "\t");
    my $str = $title[0]->text;
    undef (@title);
    $LOG->print('after undef: ', win32_size_check() - $start_usage, "\t");
    
    $_[0]->purge;            # outputs the section and frees memory
    $LOG->print('after purge: ', win32_size_check() - $start_usage, "\n");
 }

sub win32_size_check {
    # get handle on current process
    my $GetCurrentProcess = new Win32::API('kernel32', 
                                           'GetCurrentProcess', 
                                           [], 
                                           'I');
    my $hProcess = $GetCurrentProcess->Call();

    
    # memory usage is bundled up in ProcessMemoryCounters structure
    # populated by GetProcessMemoryInfo() win32 call
    my $DWORD = 'B32';  # 32 bits
    my $SIZE_T = 'I';   # unsigned integer

    # build a buffer structure to populate
    my $pmem_struct = "$DWORD" x 2 . "$SIZE_T" x 8;
    my $pProcessMemoryCounters = pack($pmem_struct, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    
    # GetProcessMemoryInfo is in "psapi.dll"
    my $GetProcessMemoryInfo = new Win32::API('psapi', 
                                              'GetProcessMemoryInfo', 
                                              ['I', 'P', 'I'], 
                                              'I');

    my $bool = $GetProcessMemoryInfo->Call($hProcess, 
                                           $pProcessMemoryCounters, 
                                           length($pProcessMemoryCounters));

    # unpack ProcessMemoryCounters structure
    my ($cb, 
        $PageFaultCount, 
        $PeakWorkingSetSize,
        $WorkingSetSize,
        $QuotaPeakPagedPoolUsage,
        $QuotaPagedPoolUsage,
        $QuotaPeakNonPagedPoolUsage,
        $QuotaNonPagedPoolUsage,
        $PagefileUsage,
        $PeakPagefileUsage) = unpack($pmem_struct, $pProcessMemoryCounters);


    my $size = int($WorkingSetSize/1024);
    return ($size);
}

memori.log
Код

start 9144
############
in row: 364    after children: 376    after undef: 376    after purge: 376
############
in row: 384    after children: 384    after undef: 384    after purge: 384
############
in row: 384    after children: 384    after undef: 384    after purge: 384
############
in row: 388    after children: 388    after undef: 388    after purge: 388
############
in row: 388    after children: 388    after undef: 388    after purge: 388
############
in row: 396    after children: 400    after undef: 400    after purge: 400
............
in row: 18208    after children: 18208    after undef: 18208    after purge: 18208
############
in row: 18216    after children: 18216    after undef: 18216    after purge: 18216
############
in row: 18220    after children: 18220    after undef: 18220    after purge: 18220


Добавлено через 1 минуту и 13 секунд
Я так понимаю не освобождается память после  undef (@title);

Добавлено через 2 минуты и 12 секунд
хотя и после purge растет :(
каждый Row приблизительно одного содержания.
PM MAIL Jabber   Вверх
ginnie
Дата 20.8.2009, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



shamber, уменьшения используемой памяти, вроде, быть не должно, т.к. интерпретатор ее системе не отдает. Не должно быть большого роста.

undef (@title); можно убрать, оно только замедляет работу, т.к. каждый вызов будет память заново выделяться.

Это сообщение отредактировал(а) ginnie - 20.8.2009, 11:35


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
shamber
Дата 20.8.2009, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(ginnie @  20.8.2009,  11:33 Найти цитируемый пост)
undef (@title)

а вот здесь в твоем посте
выделение памяти увеличивается.

PM MAIL Jabber   Вверх
ginnie
Дата 20.8.2009, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



shamber, без undef (@title) память остается зарезервирована для функции, а так как эта функция в нашем случае вызывается много раз, то это хорошо.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


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

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


 




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


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

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