I keep hearing that PHP has overhead. For example a C++ int uses 4 Bytes on a 32 bit system but a PHP int uses more. What is this value?
-
3PHP is what it is. Don't fight it :) – alex May 12 '11 at 00:52
-
4This is ridiculous. It cannot be quantified. PHP is a high-level language, the entire purpose of which is that you _do not concern yourself with this nonsense_. – Lightness Races in Orbit May 12 '11 at 01:03
-
1Based on the current vote count, it looked like we needed a comment here with 0 upvotes. – Xeoncross May 12 '11 at 01:14
-
3@Chris: You can still move the checkmark to @mu's answer instead. It's technically more correct, and should be the accepted reference answer. – mario May 12 '11 at 01:36
-
This paper might be of interest to you: http://domino.watson.ibm.com/comm/research_people.nsf/pages/nickmitchell.pubs.html/$FILE/oopsla2007-bloat.pdf The situation for PHP is almost surely much much worse. – R.. GitHub STOP HELPING ICE May 12 '11 at 01:53
-
@mario Very noble of you, I'd upvote again if possible :) – alex May 12 '11 at 02:03
-
3@Tomalak: In normal cases you don't need to concern yourself with low level details like this in PHP. However, if you need to allocate tens or hundreds of thousands of variables you do need to concern yourself with these things. Besides, it is good to have some idea how your tools work even if you don't need to know for day to day tasks. – mu is too short May 12 '11 at 03:14
2 Answers
PHP does not just store an C int
. It needs to keep type information and whatnot for each value. Each variable also needs an entry in one of the variable scope hash tables.
Not sure if this is the right snippet, but basically look for zval
in the PHP source:
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
Most integer-like types use at least a long
. (Which I assume would include the booleans from your previous questions.)
http://porteightyeight.com/2008/03/18/the-truth-about-php-variables/

- 144,265
- 20
- 237
- 291
-
Just to point out (the obvious) that `long` will vary based on the architecture PHP was was compiled for (32bit or 64bits generally). – Jun 13 '11 at 22:21
I need more space than a comment to expand on mario's findings so I'll add an answer instead.
The size of a C union
will be the size of its largest member (possibly with extra bytes to satisfy alignment constraints). For zvalue_value
, that would be the obj
which has the size of three pointers (not including the memory required for what those pointers point to):
typedef struct _zend_object {
zend_class_entry *ce;
HashTable *properties;
HashTable *guards; /* protects from __get/__set ... recursion */
} zend_object;
On a 32bit system, a zend_object
will take 24 bytes while on a 64bit system it will take 48 bytes. So, every zvalue_value
will take at least 24 or 48 bytes regardless of what data you store in it. There's also the name of the variable which consumes more memory; compiled languages generally discard the names once the compiler is done and treat values as simple sequences of bytes (so a double
takes eight bytes, a char
takes one byte, etc...).
With regards to your recent questions about PHP booleans, a simple boolean value will consume 24 or 48 bytes for the value, plus a few more bytes for the name, plus four or eight for the zend_unit
, plus four (or eight) for the two zend_uchar
s in this:
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
The zend_uchar
members will chew up four (or eight) bytes due to alignment constraints, almost every CPU wants to access memory on natural address boundaries and that means that a single byte sized member of a struct
will take up four bytes or eight bytes of memory (depending on the CPUs natural word size and alignment constraints). So, a boolean will take somewhere between 36 and 72 bytes of memory.

- 426,620
- 70
- 833
- 800
-
-
@Chris: Perl, Ruby, and Python probably suffer the same problems, all four are probably nearly the same at this level. – mu is too short May 20 '11 at 05:21
-
1Ruby (1.x reference implementation, 32bit) will store integers up to 30bits in a single "value" slot. It uses the high-order bits to determine value classification (elisp using a similar technique for integer values). I am not sure what this nonsense about a "name" is though -- what does it have to do with a *value*? – Jun 13 '11 at 22:26
-
@pst: Whose name nonsense? Mine, PHP's, or C's? So you're saying that the two extra bits (for small Ruby Fixnums) are, essentially, used to point at the Fixnum class? That would mean that Ruby is trading speed for memory, no? My experience with the Perl internals (mostly through Inline::C wrangling) suggests that they're pretty much the same as PHP's (or the other way around most likely). – mu is too short Jun 13 '11 at 22:36
-
@mu is too short What does a value have to do with a name? :( Perhaps I am missing the meaning of "name" here -- why does it need to be tracked? The extra two bits tell if it is a Fixnum (a Fixnum is a dirty liar, it is not a "real object" in said implementations) or other object (which may be a Bignum or a String or..) -- I can't recall what the other states are for. I'm not sure if it really loses speeds with the extra bit-check over all the other stuff that goes on. – Jun 13 '11 at 22:57
-
@pst: I'm pretty sure I was referring to the variable's name so "value" probably isn't the best word there; the value on its own isn't terribly useful if you can't refer to it. Fixnums are immutable so they're allowed to be dirty stinking liars; there are a few other Fixnum-specific hacks in the source too. "Everything's an object" doesn't come cheap and sometimes it is expensive enough to warrant getting filthy. – mu is too short Jun 13 '11 at 23:15
-
@mu is too short Ah. For some reason I incorrectly read the name as stored as part of the value ... but I was clearly mistaken on that and have no idea how such a notion entered my head at all now :( – Jun 13 '11 at 23:21
-
2The definite answer to all PHP memory questions is here: https://nikic.github.io/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html – Thomas Ploch Apr 27 '15 at 07:17