0

Есть ли что-то быстрее, чем dict()?

9

Я ищу более быстрый способ хранения и доступа к примерно 3 ГБ пар k:v, где k — это строка или целое число, а v — это np.array() с различными формами.

Существует ли какой-либо объект, который быстрее стандартного словаря Python для хранения и доступа к такой структуре данных? Например, может ли pandas.DataFrame быть более эффективным вариантом?

Насколько я понимаю, стандартный словарь Python — это довольно быстрая реализация хеш-таблицы. Есть ли что-то лучшее для моего конкретного случая?

4 ответ(ов)

0

Нет, я не думаю, что есть что-то быстрее, чем dict. Средняя временная сложность проверки индекса составляет O(1).

-------------------------------------------------------
Операция     |  Средний случай | Амортизированный худший случай  |
-------------------------------------------------------
Копирование[2]|    O(n)        |           O(n)                  | 
Получение     |    O(1)        |           O(n)                  | 
Установка[1]  |    O(1)        |           O(n)                  | 
Удаление      |    O(1)        |           O(n)                  | 
Итерация[2]  |    O(n)        |           O(n)                  | 
-------------------------------------------------------

P.S. Для получения дополнительной информации, вы можете ознакомиться с вики Python о временной сложности.

0

Вы можете заметить, что при сравнении времени выполнения операций над numpy.array и классическим словарем (dict), результаты показывают, что доступ к элементам массива происходит медленнее, чем к элементам словаря.

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

По результатам тестирования, время для расчетов с массивом выглядит так:

Time for array calculations: 0.07558204099999999

А для словаря:

Time for dict calculations: 0.046898419999999996

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

Таким образом, для простых случаев на малых объемах данных словарь может оказаться быстрее, но при более серьезных вычислениях и больших данных numpy обычно превосходит по производительности благодаря своей внутренней реализации.

0

Одним может показаться, что индексирование массива быстрее, чем поиск в хэш-таблице. Если бы мы могли хранить данные в массиве NumPy и предположить, что ключи — это не строки, а числа, было бы это быстрее, чем использование словаря в Python?

К сожалению, нет, потому что NumPy оптимизирован для векторных операций, а не для индивидуального поиска значений. Даже Pandas показывает еще худшие результаты. Вы можете ознакомиться с экспериментом здесь: Проверка производительности.

Другим вариантом может быть использование массива из модуля array в Python, но он не подходит для переменных значений. Чтобы это работало, вам, скорее всего, потребуется обернуть его в код на чистом Python, что сведет на нет все преимущества по производительности, которые предлагает массив.

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

0

Вы можете рассмотреть возможность хранения данных в структуре данных, такой как Trie, если ваш ключ - это строка. Для хранения и извлечения данных из Trie вам потребуется O(N), где N - это максимальная длина ключа. То же самое происходит и с вычислением хеш-функции, которая вычисляет хеш для ключа. Хеш используется для поиска и хранения в хеш-таблице. Часто мы не учитываем время или вычисления, связанные с хешированием.

Попробуйте использовать Trie, который должен демонстрировать примерно ту же производительность, возможно, даже немного быстрее (если значение хеша вычисляется, скажем, по формуле

HASH[i] = (HASH[i-1] + key[i-1]*256^i % BUCKET_SIZE) % BUCKET_SIZE 

или что-то подобное из-за коллизий, где нам необходимо использовать 256^i).

Вы можете попробовать хранить данные в Trie и посмотреть, как это будет работать.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь