An example of low memory utilization and weak types in PHP arrays

Source: Internet
Author: User
This article mainly introduces the PHP array memory utilization low and weak type detailed interpretation, with a certain reference value, interested in small partners can refer to.

This two-day task is completed ahead of time, you can take a breather to precipitate a bit, in-depth learning PHP. In fact, I would like to know about PHP performance optimization related things, but by the online sentence "PHP array memory utilization Low, C language 100MB memory array, PHP needs 1G" surprised. Does PHP really consume memory like that? I took this opportunity to learn about the way PHP is implemented in data types.

Let's do a test first:


<?php   Echo memory_get_usage (), ' <br> ';   $start = Memory_get_usage ();   $a = Array ();   for ($i =0; $i <1000; $i + +) {    $a [$i] = $i + $i;   }   $end = Memory_get_usage ();   Echo memory_get_usage (), ' <br> ';   Echo ' argv: ', ($end-$start)/1000, ' bytes ', ' <br> ';

Results obtained:

353352
437848
Argv:84.416bytes

An integer array of 1000 elements consumes memory (437848-353352) bytes, which is approximately 82KB, which means that each element occupies 84 bytes of memory. In C, an int occupies a position of 4 bytes, which is 20 times times the overall difference.

But on the Internet, Memery_get_usage () returns are not all arrays occupied, but also includes some structure of PHP itself, so, in a different way, using PHP built-in function to create an array try:


<?php   $start = Memory_get_usage ();   $a = Array_fill (0, 10000, 1);   $end = Memory_get_usage (); 10k elements Array;   Echo ' argv: ', ($end-$start)/10000, ' byte ', ' <br> ';

The output is:

Argv:54.5792byte

Slightly better than just now, but also 54 bytes, really poor 10 times times about.

The reason, but also from the bottom of the PHP implementation. PHP is a weak type of language, without int,double,string and the like, unified a ' $ ' can solve all problems. The PHP bottom is implemented by the C language and each variable corresponds to a zval structure, which is defined in detail as:


typedef struct _ZVAL_STRUCT Zval; struct _zval_struct {/   * Variable information */   zvalue_value value;   /* The value 1 12 bytes (32-bit machine is 12, 64-bit machine requires 8+4+4=16) */   Zend_uint refcount__gc;/* The number of references to this value (for GC) 4 bytes */   Zend_uchar type;    /* The active Type 1 bytes *   /Zend_uchar is_ref__gc;/* Whether This value is a reference (&) 1 bytes */};

PHP uses the union structure to store the values of the variables, and the value variable for the Zvalue_value type in Zval is a union, defined as follows:


typedef Union _ZVALUE_VALUE {   long lval;         /* Long value */   double dval;        /* Double value */   struct {/          * String value */     char *val;     int len;   } STR;    HashTable *ht;       /* Hash Table value */   zend_object_value obj;   /*object value */} Zvalue_value;

The union type occupies a memory size that is determined by the data space occupied by its largest member. In Zvalue_value, the str struct has an int of 4 bytes, and the char pointer occupies 4 bytes, so the entire Zvalue_value occupies 8 bytes of memory.

The size of the Zval is 8 + 4 + 1 + 1 = 14 bytes.

Notice what another Hashtable is doing in Zvalue_value? In Zval, arrays, strings, and objects also require additional storage structures, and the storage structure of the array is hashtable.

The Hashtable definition gives:


typedef struct _HASHTABLE {    uint ntablesize;//table length, not the    mask of the number of elements uint ntablemask;//table, always equals nTableSize-1    uint nnumofelements;//the number of elements stored in    ulong nnextfreeelement;//refers to the next empty element position in the    bucket *pinternalpointer;//foreach loop, Used to record the current traversed element position    Bucket *plisthead;    Bucket *plisttail;    Bucket **arbuckets;//The array of elements stored    dtor_func_t pdestructor;//the destructor    Zend_bool persistent;//is persisted. From this, it can be found that the PHP array can be persisted in memory without having to reload each request.    unsigned char napplycount;    Zend_bool bapplyprotection; } HashTable;

In addition to several attribute variables that record table size, the number of elements contained, buckets are used several times, how buckets are defined:


typedef struct BUCKET {    ulong H;//array index    UINT nkeylength;//The length of the string index    void *pdata;//The storage address of the actual data    void * Pdataptr; The data storage address of the introduced    struct bucket *plistnext;    struct bucket *plistlast;    struct bucket *pnext; The address of the next element of the doubly linked list    struct bucket *plast;//The next element address of the doubly linked list    char arkey[1];/* must be the last element */} bucket;

Sort of like a list, buckets are like a list node with specific data and pointers, and Hashtable is an array that holds a bunch of buckets. The implementation of multidimensional arrays in PHP, but there is another hashtable in the bucket.

It takes 39 bytes to calculate a hashtable, and a bucket needs 33 bytes. An empty array needs to occupy 14 + 39 + 33 = 86 bytes. The bucket structure requires 33 bytes, the key length of more than four bytes is appended to the bucket, and the element value is likely to be a zval structure, and each array will be assigned an array of Bucket pointers directed by Arbuckets, although it cannot be said that each additional element requires a pointer , but the situation may be worse. That's all. An array element takes up 54 bytes, almost the same as the estimate above.

From a space point of view, the average cost of small arrays is large, of course, a script will not be flooded with a large number of small arrays, you can take a small space cost to get programming quickly. But if you use an array as a container, it's a different picture, and the actual application often encounters multidimensional arrays, and the elements are mostly. A one-dimensional array of 10k elements, for example, consumes 540k of memory, whereas a two-dimensional array of 10k x 10 theoretically requires only about 6M of space, but according to Memory_get_usage, the three-dimensional array of [10k,5,2] actually consumes 23M, Small arrays are really not going to be scratched.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.