Ключ H5PY читает медленно - PullRequest
       23

Ключ H5PY читает медленно

0 голосов
/ 04 сентября 2018

Я создал набор данных с 1000 группами, каждая из которых содержит 1300 uint8 массивов различной длины (хотя каждая из них имеет фиксированный размер). Ключи представляют собой строки из ~ 10 символов. Я не пытаюсь сделать что-то хитрое во время сохранения (без разбивки, сжатия и т. Д. - данные уже сжаты).

Итерация по всем ключам происходит очень медленно при первом запуске сценария, хотя значительно ускоряется во второй раз (тот же сценарий, другой процесс вызывается позже), поэтому я подозреваю, что какое-то кэширование как-то связано. Через некоторое время производительность сбрасывается до ужасного уровня, пока я снова не подожду.

Есть ли способ хранения данных, чтобы облегчить эту проблему? Или я могу как-то по-другому это прочитать?

Упрощенный код для сохранения

with h5py.File('my_dataset.hdf5', 'w') as fp:
    for k0 in keys0:
        group = fp.create_group(k0)
        for k1, v1 in get_items(k0):
            group.create_dataset(k1, data=np.array(v1, dtype=np.uint8))

Код доступа к упрощенному ключу:

with h5py.File('my_dataset.hdf5', 'r') as fp:
    keys0 = fp.keys()
    for k0 in keys0:
        group = fp[k0]
        n += len(tuple(group.keys())

Если я отслеживаю ход выполнения этого скрипта во время «медленной фазы», ​​это занимает почти секунду для каждой итерации. Однако, если я убью его после, скажем, 100 шагов, то при следующем запуске сценария первые 100 шагов потребуют <1 с, чтобы выполнить общее количество, а затем производительность снова упадет до уровня обхода. </p>

1 Ответ

0 голосов
/ 07 сентября 2018

Хотя я все еще не уверен, почему это все еще медленно, я нашел обходной путь: объединить каждую подгруппу в одну dataset

with h5py.File('my_dataset.hdf5', 'w') as fp:
    for k0 in keys0:
        subkeys = get_subkeys(k0)
        nk = len(subkeys)
        data = fp.create_dataset(
            'data', shape=(nk,),
             dtype=h5py.special_dtype(vlen=np.dtype(np.uint8)))
        keys = fp.create_dataset('keys', shape=(nk,), dtype='S32')
        for i, (k1, v1) in enumerate(get_items(k0)):
            keys[i] = k1
            data[i] = v1
...