PHP is sometimes very inefficient in array processing, especially when the memory usage is large, which often causes the httpd process to consume too much resources. The PHP100 website once called some content and the array is too large, leading to memory overflow and apache is often paralyzed. Although a large number of array operations in PHP may have problems in programming design to a certain extent, but rough "> <LINKhref =" http://www.php
PHP is sometimes very inefficient in array processing, especially when the memory usage is large, which often causes the httpd process to consume too much resources. The PHP100 website once called some content and the array is too large, leading to memory overflow and apache is often paralyzed. Although a large number of array operations in PHP usually reflect some problems in programming, it is necessary to roughly estimate the memory occupied by arrays.
First, let's take a look at the memory occupied by the integer array of the 1000 elements:
Echo memory_get_usage (). "\ n ";
$ A = Array ();
For ($ I = 0; I I <1000; $ I ++ ){
$ A [$ I] = $ I + $ I;
}
Echo memory_get_usage (). "\ n ";
For ($ I = 1000; $ I <2000; $ I ++ ){
$ A [$ I] = $ I + $ I;
}
Echo memory_get_usage (). "\ n ";
The output is:
58176
162956
267088
An integer array of 1000 elements occupies 100 kB of memory, and each element occupies 100 bytes on average. In pure C, only 4 k is required. 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:
Echo "init mem:". memory_get_usage (). "\ n ";
$ A = array_fill (0, 10000, 1 );
Echo "10 k elements:". memory_get_usage (). ", system:". memory_get_usage (true). "\ n ";
$ B = array_fill (0, 10000, 1 );
Echo "10 k elements:". memory_get_usage (). ", system:". memory_get_usage (true). "\ n ";
Get:
Init mem: 58468
10 k elements: 724696, system: 786432
10 k elements: 1390464, system: 1572864
From this result, it seems that an array element occupies about 60 bytes. Let's look at the C structure of the array. for the array variables in PHP, we need a zval structure first:
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, which is not far from the estimation above.
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.