Я работаю над кодом для управления коллекцией уникальных объектов. Первый прототип этого кода использует ассоциативный массив, в основном, так как я всегда это делал.
Тем не менее, я также заинтересован в использовании функциональных возможностей, которые были добавлены в более современные версии PHP, такие как SplObjectStorage, для этого, частично в качестве учебного опыта, отчасти потому, что он может предложить преимущества (контрольные показатели, которые я видел, показывают, что SplObjectStorage может быть быстрее, чем массивы во многих случаях).
Текущая реализация имеет ассоциативный массив, который я проверяю с помощью in_array, чтобы узнать, находится ли объект уже в массиве, перед добавлением к нему нового объекта.
Большая проблема, которую я вижу с помощью SplObjectStorage, заключается в том, что на первый взгляд не кажется, что поддерживает поведение ассоциативного массива key / value и может рассматриваться только как индексированный массив. Однако документация для новых функций PHP не соответствует стандартам документации более установленных частей языка, и я могу просто что-то упустить.
Можно ли использовать SplObjectStorage вместо ассоциативного массива? Если да, как определить ключ при добавлении нового объекта? Что еще более важно, каковы относительные преимущества и недостатки SplObjectStorage по сравнению с ассоциативными массивами?
Вы не должны видеть SplObjectStorage
как SplObjectStorage
ключей, а просто набор объектов . Что-то в комплекте или нет, но его положение не имеет значения .
«Ключ» элемента в SplObjectStorage
на самом деле является хешем объекта. Это делает невозможным добавление нескольких экземпляров одного и того же экземпляра объекта в SplObjectStorage
, поэтому вам не нужно проверять, существует ли копия перед добавлением.
Однако в PHP 5.4
существует новый метод getHash()
который вы можете переопределить, который вернет «хэш» объекта. Это – в некотором смысле – возвращает / устанавливает ключ, чтобы вы могли его хранить в разных условиях.
Основным преимуществом SplObjectStorage
является то, что вы получаете множество методов для взаимодействия и взаимодействия с разными наборами ( contains()
, removeAll()
, removeAllExcept()
т . Д. ). Его скорость немного лучше, но использование памяти хуже, чем обычные массивы PHP.
Результаты после запуска теста с 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 | +------------------+----------------+----------------+---------+
Как вы можете видеть, массивы в 1,5 раза быстрее, чем SplObjectStorage
и используют в 1,5 раза меньше памяти .
Когда вся память, выделенная для массива, будет исчерпана, выделенная ему память будет удвоена. В этом контексте коллекция объектов может быть более эффективной структурой.