我正在编写代码来管理一组唯一对象。这段代码的第一个原型使用了一个关联数组,基本上就像我一直这样做的那样。
然而,我也热衷于利用已经添加到更现代版本的PHP中的功能,例如SplObjectStorage来实现这一目的,部分原因在于学习体验,部分原因在于它必然会提供优势(基准测试我已经看到表明SplObjectStorage在很多情况下可能比数组更快)。
当前实现有一个关联数组,我在in_array中检查它是否在向对象添加新对象之前是否已经在数组中。
我可以通过SplObjectStorage看到的一个大问题是,它似乎(乍一看)不支持键/值关联数组行为,并且只能被视为索引数组。但是,PHP较新功能的文档不符合语言中较为成熟的部分的文档标准,我可能只是遗漏了一些东西。
我可以使用SplObjectStorage代替关联数组吗?如果是这样,我如何在添加新对象时定义键?更重要的是,与关联数组相比,SplObjectStorage的相对优势和劣势是什么?
答案 0 :(得分:24)
您不应该将SplObjectStorage
视为键值存储,而只是一组对象。有什么东西在集合中,但它的位置并不重要。
SplObjectStorage
中元素的“键”实际上是对象的哈希值。这使得无法将同一对象实例的多个副本添加到SplObjectStorage
,因此您无需在添加之前检查副本是否已存在。
但是,在PHP 5.4
中有一个名为getHash()
的新方法,你可以覆盖它,它将返回对象的“哈希”。这在某种意义上 - 返回/设置密钥,以便您可以在不同条件下存储它。
SplObjectStorage
的主要优势在于您获得了许多方法来处理和交互不同的集合( contains()
,removeAll()
,removeAllExcept()
等)。它的速度稍微好一点,但内存使用情况比正常的PHP数组更差。
答案 1 :(得分:4)
在PHP 5.6.13
上运行benchmark 10000次迭代后的结果:
+------------------+----------------+----------------+---------+
| Type | Time to fill | Time to check | Memory |
+------------------+----------------+----------------+---------+
| SplObjectStorage | 0.021285057068 | 0.019490000000 | 2131984 |
| Array | 0.021125078201 | 0.020912000000 | 1411440 |
+------------------+----------------+----------------+---------+
正如您所看到的,数组比<{1}}强<1.5> 使用内存减少1.5倍。
答案 2 :(得分:0)
当分配给阵列的所有内存用完时,分配给它的内存将加倍。在这种情况下,一组对象可能是更有效的结构。