Почему быстрее читать весь набор данных hdf5, чем срез - PullRequest
0 голосов
/ 24 ноября 2018

Я пытаюсь выяснить, почему это происходит:

In [1]: import time, h5py as h5
In [2]: f = h5.File('myfile.hdf5', 'r')                                                                                                                                    
In [3]: st = time.time(); data = f["data"].value[0,:,1,...]; elapsed = time.time() - st;
In [4]: elapsed
Out[4]: 11.127676010131836
In [5]: st = time.time(); data = f["data"][0,:,1,...]; elapsed2 = time.time() - st;
In [6]: elapsed2
Out[6]: 59.810582399368286
In [7]: f["data"].shape
Out[7]: (1, 4096, 6, 16, 16, 16, 16)
In [8]: f["data"].chunks
Out[8]: (1, 4096, 1, 16, 16, 16, 16)

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

Размер фрагмента соответствует фрагменту, поэтому он должен быть непрерывной памятью, верно?Почему тогда это намного медленнее?

Набор данных сжимается с помощью gzip (opts=2).

Следуя комментарию Эндрю, я запускаю его, очищая кеши между чтениями:

elapsed1: 11.001180410385132
elapsed2: 43.19723725318909
48.61user 4.45system 0:54.65elapsed 97%CPU (0avgtext+0avgdata 8431596maxresident)k
479584inputs+0outputs (106major+3764414minor)pagefaults 0swaps

(Этот следующий прогон имел задержку 10 секунд между двумя чтениями для очистки кэшей)

elapsed1: 11.46790862083435
elapsed2: 43.438515186309814

48.54user 4.66system 1:05.71elapsed 80%CPU (0avgtext+0avgdata 8431944maxresident)k
732504inputs+0outputs (220major+3764449minor)pagefaults 0swaps

1 Ответ

0 голосов
/ 26 ноября 2018

Сначала я запустил собственный тест.У меня нет вашего файла HDF5, поэтому я использую один из моих тестовых файлов.Мой набор тестовых таблиц содержит ~ 54 000 строк (что кажется больше, чем у вас).
Результат синхронизации с .value [] дает

>>> elapsed
0.15540122985839844

Результат синхронизации с индексированием NumPy дает:

>>> elapsed2
0.12980079650878906

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

Небольшое чтение самой последней документации по h5py содержит некоторые интересные комментарии о Dataset.value (из выпуска 2.8.0 - июнь 05, 2018; выделено мое):
Свойство Dataset.value устарело.
Свойство Dataset.value, которое относится к h5py 1.0, устарело и будет удалено в более позднем выпуске, Это свойство выводит весь набор данных в массив NumPy. Код, использующий .value, должен быть обновлен для использования индексирования NumPy, используя mydataset[...] или mydataset[()] в зависимости от ситуации.

Ваши временные тесты, кажется, противоречат отмеченному выше наблюдению.

Я думаю, вам нужно попросить разработчика h5py прокомментировать различия в производительности (и где хранятся данные - в памяти по сравнению с диском)).Вы проверили с h5py пользовательской группой ?

Редактировать: После публикации я нашел эти вопросы и ответы.Он содержит много хороших комментариев и включает ответы от разработчика h5py:
h5py: правильный способ нарезать наборы данных массива

...