34

I'm working on code to manage a collection of unique objects. The first prototype of this code utilises an associative array, basically as that's the way I've always done it.

However, I'm also keen on taking advantage of functionality that's been added to more modern versions of PHP such as [SplObjectStorage][1] for doing this instead, partly as a learning experience, partly because it's bound to offer advantages (benchmarks I've seen suggest that SplObjectStorage can be faster than arrays in a lot of cases).

The current implementation has an associative array that I check with in_array() to see if an object is already in the array before adding a new object to it.

The big problem I can see with SplObjectStorage is that it doesn't seem (at first glance) to support key/value associative array behaviour, and can only be treated as an indexed array. However, the documentation for the newer features of PHP isn't up to the standards of the documentation of more established parts of the language and I might simply be missing something.

Can I use SplObjectStorage in place of an associative array? If so, how do I define the key when adding a new object? More importantly, what are the relative advantages and disadvantages of SplObjectStorage when compared to associative arrays?

pbarney
  • 2,529
  • 4
  • 35
  • 49
GordonM
  • 31,179
  • 15
  • 87
  • 129
  • 1
    possible duplicate of [SplObjectStorage doesn't work with String, what to do?](http://stackoverflow.com/questions/1501726/splobjectstorage-doesnt-work-with-string-what-to-do) – ajreal Dec 15 '11 at 12:50
  • 3
    @ajreal: I don't think my question is all that similar to the one you indicated. – GordonM Dec 15 '11 at 12:56
  • 3
    Took a closer look, but still don't see how my problem (Can you use SplObjectStorage in place of an **associative** array and if so what are the benefits and drawbacks?) is a duplicate of that one (Why can't I put strings in an SplObjectStorage?) – GordonM Dec 16 '11 at 07:46
  • I think the question has suggested if you want to do associate array, then use the spl object hash, and attach to spl storage object. Drawback? is troublesome. The benefits of spl storage object is because is using index key (see the implementation only use next,prev to advancing the pointer).And putting back to associate key is just defeat the purpose. This is what I thinking. – ajreal Dec 16 '11 at 07:53

3 Answers3

29

You shouldn't see the SplObjectStorage as a key-value store, but merely a set of objects. Something is in the set or not, but its position is not important.

The "key" of an element in the SplObjectStorage is in fact the hash of the object. It makes it that it is not possible to add multiple copies of the same object instance to an SplObjectStorage, so you don't have to check if a copy already exists before adding.

However, in PHP 5.4 there is a new method called getHash() which you can override that will return the "hash" of the object. This - in a sense - returns/set the key so you can allow it to store under different conditions.

The main advantage of SplObjectStorage is the fact that you gain lots of methods for dealing and interacting with different sets (contains(), removeAll(), removeAllExcept() etc). Its speed is marginally better, but the memory usage is worse than normal PHP arrays.

halfer
  • 19,824
  • 17
  • 99
  • 186
JayTaph
  • 2,846
  • 1
  • 22
  • 29
  • 5
    In my experiments splObjectStorage actually used less memory than an set of arrays storing the object's hash. – Anther Feb 06 '13 at 20:59
  • 4
    I actually ran a speed test, which has been published here: http://www.technosophos.com/content/php-splobjectstorage-v-arrays-redux SPLObjectStorage seems to have a sweetspot of about 10,000 DOMDocuments, after which performance degrades. – Frederik Krautwald Sep 16 '13 at 01:04
  • Hey, maybe this is just an oversimplification of what it does, but SplObjectStore is specifically for using objects as keys, paired to some arbitrary value...and not just a set of objects. – Christian Apr 11 '23 at 11:28
12

Results after running this benchmark with 10,000 iterations on PHP 5.6.13:

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

Arrays use 34% less memory and are about the same speed as SplObjectStorage.


Results with PHP 7.4.27:

Type Time to fill Time to check Memory
SplObjectStorage 0.019295692444 0.016039848328 848384
Array 0.024008750916 0.022011756897 3215416

Arrays use 3.8 times more memory and are 24% slower than SplObjectStorage.


Results with PHP 8.1.1:

Type Time to fill Time to check Memory
SplObjectStorage 0.009704589844 0.003775596619 768384
Array 0.014604568481 0.012760162354 3215416

Arrays use 4.2 times more memory and are 50% slower than SplObjectStorage.

rid
  • 61,078
  • 31
  • 152
  • 193
Roman Liukshyn
  • 153
  • 1
  • 3
1

When all the memory allocated to array is used up, the memory allocated to it will be doubled. In this context, a collection of objects may be more effective structure.

John Smith
  • 1,091
  • 9
  • 17