Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the actual memory cost of storing an integer?

lets say I just do this

$arr = array();
for ($i = 0; $i < 10; $i++) $arr[] = $i;

So I store 10 integers in an array. If the integer is a 32b one, the memory cost should be 40 bytes. Problem is, I didn't tell php that it is an integer so it either has to store it as something else? (js likes to make doubles for example) or keep extra data to remind itself what it is? How much memory do those 10 numbers + the array actually take up in system memory?

Its important since I'm trying to assess the viability of an algorithm I'd like to port to php and its kinda heavy on the memory.

like image 873
user81993 Avatar asked Mar 13 '23 13:03

user81993


1 Answers

Your question cannot be easily answered because the exact memory footprint depends on a couple of factors, some of which I'll try to outline below.

If you just need some quick numbers, consider:

  • memory_get_usage — Returns the amount of memory allocated to PHP
  • memory_get_peak_usage — Returns the peak of memory allocated by PHP

PHP stores values internally in a structure called the zval:

121 struct _zval_struct {
122    zend_value        value;            /* value */
123    union {
124        struct {
125            ZEND_ENDIAN_LOHI_4(
126                zend_uchar    type,         /* active type */
127                zend_uchar    type_flags,
128                zend_uchar    const_flags,
129                zend_uchar    reserved)     /* call info for EX(This) */
130        } v;
131        uint32_t type_info;
132    } u1;
133    union {
134        uint32_t     var_flags;
135        uint32_t     next;                 /* hash collision chain */
136        uint32_t     cache_slot;           /* literal cache slot */
137        uint32_t     lineno;               /* line number (for ast nodes) */
138        uint32_t     num_args;             /* arguments number for EX(This) */
139        uint32_t     fe_pos;               /* foreach position */
140        uint32_t     fe_iter_idx;          /* foreach iterator index */
141    } u2;
142};

This is a union type, meaning it can store values of multiple types. So yes, it keeps extra data to remind itself what it is. Integers are usually represented as longs (32 or 64 bit depending on your platform).

As for arrays, there is an excellent blog post by NikiC giving a detailed explanation. The gist:

                              |  64 bit   | 32 bit
---------------------------------------------------
zval                         |  24 bytes | 16 bytes
+ cyclic GC info             |   8 bytes |  4 bytes
+ allocation header          |  16 bytes |  8 bytes
===================================================
zval (value) total           |  48 bytes | 28 bytes
===================================================
bucket                       |  72 bytes | 36 bytes
+ allocation header          |  16 bytes |  8 bytes
+ pointer                    |   8 bytes |  4 bytes
===================================================
bucket (array element) total |  96 bytes | 48 bytes
===================================================
total total                  | 144 bytes | 76 bytes

The above numbers will vary depending on your operating system, your compiler and your compile options. E.g. if you compile PHP with debug or with thread-safety, you will get different numbers. But I think that the sizes given above are what you will see on an average 64-bit production build of PHP 5.3 on Linux.

It's also worth noting that non-numeric array key labels are an allocation as well, so the longer the labels, the more memory they consume obviously.

The numbers above also depend on which version of PHP you are using. The memory footprint of PHP >= 7 should be much lower than for any PHP < 7 due to internal changes to the Zend Engine. See these two blog posts for details:

  • https://nikic.github.io/2015/05/05/Internal-value-representation-in-PHP-7-part-1.html
  • https://nikic.github.io/2015/06/19/Internal-value-representation-in-PHP-7-part-2.html

Also see these resources for more info:

  • http://php.net/manual/en/internals2.variables.intro.php
  • http://blog.ircmaxell.com/2012/03/phps-source-code-for-php-developers_21.html
like image 173
Gordon Avatar answered Mar 15 '23 03:03

Gordon