Подтвердить что ты не робот

Ассоциативный массив против SplObjectStorage

Я работаю над кодом для управления коллекцией уникальных объектов. Первый прототип этого кода использует ассоциативный массив, в основном так, как я всегда это делал.

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

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

Большая проблема, которую я вижу с помощью SplObjectStorage, заключается в том, что на первый взгляд не кажется, что поддерживает поведение ассоциативного массива key/value и может рассматриваться только как индексированный массив. Однако документация для новых функций PHP не соответствует стандартам документации более установленных частей языка, и я могу просто что-то упустить.

Можно ли использовать SplObjectStorage вместо ассоциативного массива? Если да, как определить ключ при добавлении нового объекта? Что еще более важно, каковы относительные преимущества и недостатки SplObjectStorage по сравнению с ассоциативными массивами?

4b9b3361

Ответ 1

Вы не должны видеть SplObjectStorage как хранилище ключей, а просто набор объектов. Что-то в комплекте или нет, но его позиция не важна.

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

Однако в PHP 5.4 есть новый метод под названием getHash(), который вы можете переопределить, который вернет "хэш" объекта. Это - в некотором смысле - возвращает/устанавливает ключ, чтобы вы могли его хранить в разных условиях.

Основным преимуществом SplObjectStorage является то, что вы получаете множество методов для работы и взаимодействия с разными наборами (contains(), removeAll(), removeAllExcept() и т.д.). Его скорость немного лучше, но использование памяти хуже, чем обычные массивы PHP.

Ответ 2

Результаты после запуска теста с 10000 итерациями на PHP 5.6.13:

+------------------+----------------+----------------+---------+
|       Type       |  Time to fill  | Time to check  | Memory  |
+------------------+----------------+----------------+---------+
| SplObjectStorage | 0.021285057068 | 0.019490000000 | 2131984 |
| Array            | 0.021125078201 | 0.020912000000 | 1411440 |
+------------------+----------------+----------------+---------+

Как видите, Array не заметно быстрее, чем SplObjectStorage, но использует на 34% меньше памяти.

Ответ 3

Когда вся память, выделенная для массива, будет исчерпана, выделенная ему память будет удвоена. В этом контексте коллекция объектов может быть более эффективной структурой.