Http://blog.csdn.net/hguisu/article/details/7376705
As mentioned in the previous PHP efficient writing, do not copy variables, especially arrays, whenever possible. In general, the memory usage of PHP arrays is only 1/10. That is to say, an array of 100 MB memory in C language requires 1 GB in PHP. We can roughly estimate the memory occupied by the PHP array. First, we test the memory occupied by the integer of the 1000 elements:
<?php echo memory_get_usage() , '<br>'; $start = memory_get_usage(); $a = Array(); for ($i=0; $i<1000; $i++) { $a[$i] = $i + $i; } $mid = memory_get_usage(); echo memory_get_usage() , '<br>'; for ($i=1000; $i<2000; $i++) { $a[$i] = $i + $i; } $end = memory_get_usage(); echo memory_get_usage() , '<br>'; echo 'argv:', ($mid - $start)/1024 ,'kb' , '<br>'; echo 'argv:',($end - $mid)/1024 ,'kb' , '<br>';
The output is:
350752
435248
519424
Argv: 84.416 byte
Argv: 84.176 byte
The integer array of 1000 elements occupies 82 KB of memory, and each element occupies 84 bytes on average. In pure C, only 4 K is required (an integer occupies 4 bytes * 1000 ). The results returned by memory_get_usage () are not all occupied by arrays, but also include some structures allocated by PHP running itself. The arrays generated by built-in functions may be closer to the actual space:
<?php $start = memory_get_usage(true); $a = array_fill(0, 10000, 1); $mid = memory_get_usage(true); //10k elements array; echo 'argv:', ($mid - $start )/10000,'byte' , '<br>'; $b = array_fill(0, 10000, 1); $end = memory_get_usage(true); //10k elements array; echo 'argv:', ($end - $mid)/10000 ,'byte' , '<br>';
Get:
Argv: 54.5792 byte
Argv: 54.5792 byte
From this result, it seems that an array element occupies about 54 bytes. Let's take a look at the C structure of the array in Zend and the array variable in PHP. First, we need a zval structure:
Struct _ zval_struct{
Zvalue_value value;
Zend_uint refcount _ GC;
Zend_uchar type;
Zend_uchar is_ref _ GC;
};
Zvalue_value is a union:
Typedef union _ zvalue_value {
Long lval;
Double dval;
Struct {
Char * val;
Int Len;
} STR;
Hashtable * HT;
Zend_object_value OBJ;
}Zvalue_value;
Generally, the zval structure requires 8 + 6 = 14 bytes. in PHP, each variable has a corresponding zval. However, arrays, strings, and objects also require another storage structure, the array is a hashtable:
Typedef struct _ hashtable {
Uint ntablesize;
Uint ntablemask;
Uint nnumofelements;
Ulong nnextfreeelement;
Bucket * pinternalpointer;
Bucket * plisthead;
Bucket * plisttail;
Bucket ** arbuckets;
Dtor_func_t pdestructor;
Zend_bool persistent;
Unsigned char napplycount;
Zend_bool bapplyprotection;
}Hashtable;
The hashtable structure requires 40 bytes, and each array element is stored in the bucket structure:
Typedef struct bucket {
Ulong h;
Uint nkeylength;
Void * pdata;
Void * pdataptr;
Struct bucket * plistnext;
Struct bucket * plistlast;
Struct bucket * pnext;
Struct bucket * plast;
Char arkey [1];
}Bucket;
The bucket structure requires 36 bytes. The key length of more than four bytes is appended to the bucket, and the element value is probably a zval structure, in addition, each array is allocated with a bucket pointer array pointed to by arbuckets. Although it cannot be said that a pointer is required for every addition of an element, the actual situation may be worse. In this case, an array element occupies 54 bytes, almost the same as the above estimation.
An empty array occupies at least 14 (zval) + 40 (hashtable) + 32 (arbuckets) = 86 bytes. As a variable, it should have a position in the symbol table, it is also an array element, so an empty array variable requires 118 bytes to describe and store. From the perspective of space, the average cost of small arrays is relatively high. Of course, a script won't fill a large number of small arrays, so you can get the programming speed at a small space cost. However, using arrays as containers is another scene. In actual applications, multi-dimensional arrays are often used, and many elements exist. For example, a one-dimensional array with 10 k elements consumes about K of memory, while a 10 k x 10 two-dimensional array requires about 6 m in theory, but the results of memory_get_usage are twice the total space, the 3D array of [10 K, 5, 2] actually consumes 23 MB, and small arrays cannot be included.
Http://blog.csdn.net/hguisu/article/details/7376705
As mentioned in the previous PHP efficient writing, do not copy variables, especially arrays, whenever possible. In general, the memory usage of PHP arrays is only 1/10. That is to say, an array of 100 MB memory in C language requires 1 GB in PHP. We can roughly estimate the memory occupied by the PHP array. First, we test the memory occupied by the integer of the 1000 elements:
<?php echo memory_get_usage() , '<br>'; $start = memory_get_usage(); $a = Array(); for ($i=0; $i<1000; $i++) { $a[$i] = $i + $i; } $mid = memory_get_usage(); echo memory_get_usage() , '<br>'; for ($i=1000; $i<2000; $i++) { $a[$i] = $i + $i; } $end = memory_get_usage(); echo memory_get_usage() , '<br>'; echo 'argv:', ($mid - $start)/1024 ,'kb' , '<br>'; echo 'argv:',($end - $mid)/1024 ,'kb' , '<br>';
The output is:
350752
435248
519424
Argv: 84.416 byte
Argv: 84.176 byte
The integer array of 1000 elements occupies 82 KB of memory, and each element occupies 84 bytes on average. In pure C, only 4 K is required (an integer occupies 4 bytes * 1000 ). The results returned by memory_get_usage () are not all occupied by arrays, but also include some structures allocated by PHP running itself. The arrays generated by built-in functions may be closer to the actual space:
<?php $start = memory_get_usage(true); $a = array_fill(0, 10000, 1); $mid = memory_get_usage(true); //10k elements array; echo 'argv:', ($mid - $start )/10000,'byte' , '<br>'; $b = array_fill(0, 10000, 1); $end = memory_get_usage(true); //10k elements array; echo 'argv:', ($end - $mid)/10000 ,'byte' , '<br>';
Get:
Argv: 54.5792 byte
Argv: 54.5792 byte
From this result, it seems that an array element occupies about 54 bytes. Let's take a look at the C structure of the array in Zend and the array variable in PHP. First, we need a zval structure:
Struct _ zval_struct{
Zvalue_value value;
Zend_uint refcount _ GC;
Zend_uchar type;
Zend_uchar is_ref _ GC;
};
Zvalue_value is a union:
Typedef union _ zvalue_value {
Long lval;
Double dval;
Struct {
Char * val;
Int Len;
} STR;
Hashtable * HT;
Zend_object_value OBJ;
}Zvalue_value;
Generally, the zval structure requires 8 + 6 = 14 bytes. in PHP, each variable has a corresponding zval. However, arrays, strings, and objects also require another storage structure, the array is a hashtable:
Typedef struct _ hashtable {
Uint ntablesize;
Uint ntablemask;
Uint nnumofelements;
Ulong nnextfreeelement;
Bucket * pinternalpointer;
Bucket * plisthead;
Bucket * plisttail;
Bucket ** arbuckets;
Dtor_func_t pdestructor;
Zend_bool persistent;
Unsigned char napplycount;
Zend_bool bapplyprotection;
}Hashtable;
The hashtable structure requires 40 bytes, and each array element is stored in the bucket structure:
Typedef struct bucket {
Ulong h;
Uint nkeylength;
Void * pdata;
Void * pdataptr;
Struct bucket * plistnext;
Struct bucket * plistlast;
Struct bucket * pnext;
Struct bucket * plast;
Char arkey [1];
}Bucket;
The bucket structure requires 36 bytes. The key length of more than four bytes is appended to the bucket, and the element value is probably a zval structure, in addition, each array is allocated with a bucket pointer array pointed to by arbuckets. Although it cannot be said that a pointer is required for every addition of an element, the actual situation may be worse. In this case, an array element occupies 54 bytes, almost the same as the above estimation.
An empty array occupies at least 14 (zval) + 40 (hashtable) + 32 (arbuckets) = 86 bytes. As a variable, it should have a position in the symbol table, it is also an array element, so an empty array variable requires 118 bytes to describe and store. From the perspective of space, the average cost of small arrays is relatively high. Of course, a script won't fill a large number of small arrays, so you can get the programming speed at a small space cost. However, using arrays as containers is another scene. In actual applications, multi-dimensional arrays are often used, and many elements exist. For example, a one-dimensional array with 10 k elements consumes about K of memory, while a 10 k x 10 two-dimensional array requires about 6 m in theory, but the results of memory_get_usage are twice the total space, the 3D array of [10 K, 5, 2] actually consumes 23 MB, and small arrays cannot be included.