Проблема производительности с циклом в наборах данных с h5py

Я хочу применить простую функцию к наборам данных, содержащимся в файле hdf5. Я использую код, подобный этому

import h5py
data_sums = []

with h5py.File(input_file, "r") as f:
    for (name, data) in f["group"].iteritems():
        print name
        # data_sums.append(data.sum(1))
        data[()]  # My goal is similar to the line above but this line is enough
                  # to replicate the problem

Вначале он идет очень быстро, а после определенного количества, до некоторой степени воспроизводимого набора данных, резко замедляется. Если я прокомментирую последнюю строку, она закончится почти мгновенно. Неважно, сохраняются данные (здесь добавляются к списку) или нет: что-то вроде data[:100] как аналогичный эффект. Количество наборов данных, которые можно обработать до падения производительности, зависит от размера части, доступ к которой осуществляется на каждой итерации. Итерация по более мелким фрагментам не решает проблему.

Я предполагаю, что я заполняю некоторое пространство памяти, и процесс замедляется, когда он заполнен, но я не понимаю, почему.

Как обойти эту проблему производительности?

Я запускаю Python 2.6.5 на Ubuntu 10.04.

Изменить: следующий код не замедляется, если вторая строка цикла не закомментирована. Это замедляет без него

f = h5py.File(path to file, "r")
list_name = f["data"].keys()
f.close()

import numpy as np

for name in list_name:
    f = h5py.File(d.storage_path, "r")
    # name = list_name[0] # with this line the issue vanishes.
    data = f["data"][name]
    tag = get_tag(name)
    data[:, 1].sum()
    print "."

    f.close()

Изменить: я обнаружил, что доступ к первому измерению многомерных наборов данных работает без проблем. Проблема возникает, когда задействованы более высокие измерения.


person M. Toya    schedule 23.09.2013    source источник


Ответы (1)


Платформа?

в Windows 64 бит, Python 2.6.6, я видел некоторые странные проблемы при пересечении барьера в 2 ГБ (я думаю), если вы выделили его небольшими кусками.

вы можете увидеть это с помощью скрипта следующим образом:

ix = []
for i in xrange(20000000):
    if i % 100000 == 0:
        print i
    ix.append('*' * 1000)

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

но если вы запустите его в больших блоках:

ix = []
for i in xrange(20000):
    if i % 100000 == 0:
        print i
    ix.append('*' * 1000000)

похоже, у него нет проблемы (хотя у него закончится память, в зависимости от того, сколько у вас есть - здесь 8 ГБ).

еще более странно, если вы съедаете память, используя большие блоки, а затем снова очищаете память (ix=[] снова, так что память почти не используется), а затем повторно запускаете тест малых блоков, он больше не медленный .

я думаю, что была некоторая зависимость от версии pyreadline - 2.0-dev1 очень помог с такими проблемами. но не помните слишком много. когда я попробовал это сейчас, я больше не вижу этой проблемы - оба значительно замедляются около 4,8 ГБ, что со всем остальным, что у меня работает, примерно там, где оно достигает пределов физической памяти и начинает подкачку.

person Corley Brigman    schedule 23.09.2013
comment
Я запускаю Python 2.6.5 на Ubuntu 10.04. Вы предлагаете мне обновить мой дистрибутив Python? - person M. Toya; 23.09.2013
comment
У меня аналогичная проблема с производительностью, даже если я не храню данные в списке. Доступа к ним достаточно, и использование памяти все время остается на низком уровне. - person M. Toya; 23.09.2013
comment
ну, в 2.6.6 есть некоторые исправления безопасности, которых нет в 2.6.5, но в остальном это не должно иметь никакого значения. Возможно ли, что у вас просто разная длина данных? то есть было бы полезно запустить его и распечатать len(data) и посмотреть, сильно ли меняются длины... - person Corley Brigman; 01.10.2013