Live data from Hacker News

How big are PHP arrays (and values) really?

nikic.github.com

41–50 of 90 posts

Re: How big are PHP arrays (and values) really?

#41

> A union is a means to make some value accessible as various types. For example if you do a zvalue_value->lval you’ll get the value interpreted as an integer. If you use zvalue_value->ht on the other hand the value will be interpreted as a pointer to a hashtable (aka array). This is not valid C usage of unions. They are _only_ for use as a method to save space, not for conversion between types, despite it being a ve…

I don't see how unions could save space, care to explain?

If you have multiple items of which you're only going to store one at a time but want them in the same "structure" then you use a union. (i.e. temporally disjoint)

Re: How big are PHP arrays (and values) really?

#42

> A union is a means to make some value accessible as various types. For example if you do a zvalue_value->lval you’ll get the value interpreted as an integer. If you use zvalue_value->ht on the other hand the value will be interpreted as a pointer to a hashtable (aka array). This is not valid C usage of unions. They are _only_ for use as a method to save space, not for conversion between types, despite it being a ve…

Actually, the upcoming C1X standard makes type punning via union legal. In C99, alias analysis works behaves exactly as you said, but using unions to convert between floats and ints is so common that it's legal in C1X, VC++, and I believe gcc.

Re: How big are PHP arrays (and values) really?

#43
post #25

php is not unique in having big memory footprint. AFAIC Python and Ruby are also memory hogs. An interesting question is how memory efficient a dynamic PL can be. Given that in modern computers memory access (cache misses) is fairly expensive it probably makes sense to trade instructions for memory.

> AFAIC Python and Ruby are also memory hogs. Even more so in some areas, for instance a Python `int` is not a machine integer but a full-blown object.

It's only always a full-blown object in CPython. Smarter implementations, notably PyPy, will do escape analysis, and never actually end up allocating those objects.

(My point is that not having unboxed types does not imply being a memory hog. You just need a smarter implementation.)

Re: How big are PHP arrays (and values) really?

#44

> A union is a means to make some value accessible as various types. For example if you do a zvalue_value->lval you’ll get the value interpreted as an integer. If you use zvalue_value->ht on the other hand the value will be interpreted as a pointer to a hashtable (aka array). This is not valid C usage of unions. They are _only_ for use as a method to save space, not for conversion between types, despite it being a ve…

Actually, the upcoming C1X standard makes type punning via union legal. In C99, alias analysis works behaves exactly as you said, but using unions to convert between floats and ints is so common that it's legal in C1X, VC++, and I believe gcc.

gcc does in some cases but not all (see http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Optimize-Options... but not all).

Still, the current standard says it's not legal so it seems like a bad idea to rely on undefined behaviour...

Re: How big are PHP arrays (and values) really?

#45

> A union is a means to make some value accessible as various types. For example if you do a zvalue_value->lval you’ll get the value interpreted as an integer. If you use zvalue_value->ht on the other hand the value will be interpreted as a pointer to a hashtable (aka array). This is not valid C usage of unions. They are _only_ for use as a method to save space, not for conversion between types, despite it being a ve…

PHP isn't using it for type punning, they are using it to save space. The article author was a bit unclear here.

When PHP needs to convert a type it does it properly, not through the union.

Re: How big are PHP arrays (and values) really?

#46
post #3

PHP arrays are not really arrays, they are sort of hash-maps. You can do things like $arr = array(1 => 10, "1" => 11); Or even $arr = array('他妈的我的生活' => 5); But at the same time you can treat them as regular zero-based arrays. $arr = array(); $arr[] = 1; $arr[] = 2; $arr[] = 3; $arr[] = 'dog';

It is the same for Javascript: even though you have an Array object that you can instantiate instead of the more generic Object, they are much the same thing under the hood with both arrays and objects being hash maps [you can use the two interchangably to an extent (if you don't need the extra functinos defined by the array prototype) - references object properies in an hash-like manner or array contents the same wa…

It is the same for Javascript: even though you have an Array object that you can instantiate instead of the more generic Object, they are much the same thing under the hood with both arrays and objects being hash maps

While this is true if you only consider language semantics, implementions do use actual arrays to store dense properties with integer names, ie arrays are backed by both flat and sparse storage with some heuristic algorithm to determine when to use what.

Re: How big are PHP arrays (and values) really?

#47

> A union is a means to make some value accessible as various types. For example if you do a zvalue_value->lval you’ll get the value interpreted as an integer. If you use zvalue_value->ht on the other hand the value will be interpreted as a pointer to a hashtable (aka array). This is not valid C usage of unions. They are _only_ for use as a method to save space, not for conversion between types, despite it being a ve…

Actually, the upcoming C1X standard makes type punning via union legal. In C99, alias analysis works behaves exactly as you said, but using unions to convert between floats and ints is so common that it's legal in C1X, VC++, and I believe gcc.

Type-punning through unions is already legal in C99, but there's a known error in Annex J, listing it incorrectly as unspecified behaviour.

See http://stackoverflow.com/a/8513748/48015

Re: How big are PHP arrays (and values) really?

#48

> A union is a means to make some value accessible as various types. For example if you do a zvalue_value->lval you’ll get the value interpreted as an integer. If you use zvalue_value->ht on the other hand the value will be interpreted as a pointer to a hashtable (aka array). This is not valid C usage of unions. They are _only_ for use as a method to save space, not for conversion between types, despite it being a ve…

This is not valid C usage of unions. They are _only_ for use as a method to save space, not for conversion between types

That's incorrect. The following footnote was added to section 6.5.2.3 with TC3 in 2007 to clear up this particular misconception:

"If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation."

Re: How big are PHP arrays (and values) really?

#49
post #47

Earlier quoted context omitted.

Actually, the upcoming C1X standard makes type punning via union legal. In C99, alias analysis works behaves exactly as you said, but using unions to convert between floats and ints is so common that it's legal in C1X, VC++, and I believe gcc.

Type-punning through unions is already legal in C99, but there's a known error in Annex J, listing it incorrectly as unspecified behaviour. See http://stackoverflow.com/a/8513748/48015

I stand corrected :/

Re: How big are PHP arrays (and values) really?

#50

Interesting. Wonder how this compares to python and ruby memory handling.

Lua is actually closer to PHP in how arrays are used in it.

"Until Lua 4.0, tables were implemented strictly as hash tables: all pairs were explicitly stored. Lua 5.0 brought a new algorithm to optimize the use of tables as arrays: it optimizes pairs with integer keys by not storing the keys and storing the values in an actual array. More precisely, in Lua 5.0, tables are implemented as hybrid data structures: they contain a hash part and an array part. Figure 2 shows a possible configuration for a table with the pairs "x" → 9.3, 1 → 100, 2 → 200, 3 → 300. Note the array part on the right: it does not store the integer keys. This division is made only at a low implementation level; access to table fields is transparent, even to the virtual machine. Tables automatically and dy- namically adapt their two parts according to their contents: the array part tries to store the values corresponding to integer keys from 1 to some limit n. Values corresponding to non-integer keys or to integer keys outside the array range are stored in the hash part.

When a table needs to grow, Lua recomputes the sizes for its hash part and its array part. Either part may be empty. The computed size of the array part is the largest n such that at least half the slots between 1 and n are in use (to avoid wasting space with sparse arrays) and there is at least one used slot between n/2 + 1 and n (to avoid a size n when n/2 would do). After computing the new sizes, Lua creates the new parts and re-inserts the elements from the old parts into the new ones. As an example, suppose that a is an empty table; both its array part and hash part have size zero. If we execute a[1]=v, the table needs to grow to accommodate the new key. Lua will choose n = 1 for the size of the new array part (with a single entry 1 → v). The hash part will remain empty."

From "Implementation of Lua 5.0" -- http://lua.org/doc/jucs05.pdf

Post reply on HN