Arrays of PHP and SPL fixed arrays
PHP fixed arrays are part of a data structure of the PHP standard library (SPL). Compared to PHP normal arrays, fixed arrays can only be used to define its subscript, and, as the name suggests, is fixed length, its advantage is less than the normal array of memory consumption, and faster, specific reasons for the next analysis, a simple test, the first to put 10W a into the array.
Define ("MAX", 100000),//simple arrayfunction Simple_arr () { $i = MAX; $arr = Array (); while ($i-) $arr [$i]= ' a ';} Fix ArrayFunction Fix_arr () {$i = MAX; $arr = new Splfixedarray (max); while ($i-) $arr [$i]= ' a ';} Fix array with setfunction Fix_set_arr () {$i = max; $arr = new Splfixedarray (max) and while ($i-) $arr->offsetset ($i, "a") ;}
Time consumption
General array: 0.084696054458618
Fixed array: 0.048405885696411
Fixed array call Offsetset method copy: 0.27650499343872
Memory consumption
General array: 9324672
Fixed array: 4800464
Fixed array call Offsetset method copy: 4800344
Comparison of space consumption
In terms of space and time efficiency, a fixed array consumes less than a typical array. Fixed arrays with built-in functions in the extension offsetset assignment is much slower than passing the subscript, this is because the built-in method in the extension to the array assignment, PHP internal need to query the function table more than once.
In the space aspect, for the general array, PHP inside is stored through Hashtable, each slot in the Hashtable corresponds to a value in the array, in the PHP source code ZEND/ZEND_HASH.H defines the hash-related structure definition and function.
typedef struct BUCKET {ULONG h;/* used for numeric indexing */uint nkeylength;void *pdata;void *pdataptr;struct bucket *PL Istnext;struct bucket *plistlast;struct bucket *pnext;struct bucket *plast;const char *arkey;} bucket;typedef struct _hashtable {uint ntablesize;uint ntablemask;uint nnumofelements;ulong nnextfreeelement; Bucket *pinternalpointer;/* used for element traversal */bucket *plisthead; Bucket *plisttail; Bucket **arbuckets;dtor_func_t pdestructor;zend_bool persistent;unsigned Char napplycount;zend_bool bApplyProtection ; #if zend_debugint inconsistent; #endif} HashTable
As shown in the above code, a PHP array of 10 elements is the space for sizeof (HashTable) + ten * Size (Bucket) + elements themselves occupy space, this is the code level of arithmetic, in fact, in PHP is a bit more complex, HashTable ntablesize is always 2^n, so even 10 elements, PHP internal through a simple algorithm can occupy 2^4, that is, 16 slots, so the actual space is sizeof (HashTable) + * sizeof (Bucket) The + element itself occupies space. (The calculation of space only takes into account that the subscript is an integer case)
The corresponding fixed array initializes the array directly from the size of the user-descendant, as shown in the following code: An array of the same 10 elements requires only 10 of the space that the element itself occupies.
static void Spl_fixedarray_init (Spl_fixedarray *array, long size TSRMLS_DC)/* {{*/{if (Size > 0) {array->size = 0 ; /* Reset size in case ecalloc () Fails */array->elements = ecalloc (size, sizeof (Zval *)); array->size = size;} else {array->elements = Null;array->size = 0;}}
Comparison of Time
For fixed arrays, the application of memory is one step, when the memory is not enough time will be error, when the memory is not finished, it is wasted there.
For an ordinary array, because it is the dynamic allocation of array space, because it is not known how many elements, PHP initializes an empty array when the default 8 slots, but the slot is not enough time, will be allocated * * space, when the number of elements is greater than the ntablesize in Hashtbale, Will resize and rehash hashTable, in the process of resize and rehash, time consumption is considerable.
static int zend_hash_do_resize (HashTable *ht) {Bucket **t; #ifdef zend_signalstsrmls_fetch (); #endifIS_CONSISTENT (HT); if ((ht->ntablesize << 1) > 0) {/* let ' s double the table size */t = (Bucket * *) perealloc_recoverable (ht-> Arbuckets, (ht->ntablesize << 1) * sizeof (Bucket *), ht->persistent); if (t) {handle_block_interruptions (); Ht->arbuckets = T;ht->ntablesize = (ht->ntablesize << 1); ht->ntablemask = Ht->ntablesize-1;zend_ Hash_rehash (HT); Handle_unblock_interruptions (); return SUCCESS;} return FAILURE;} return SUCCESS;} Zend_api int Zend_hash_rehash (HashTable *ht) {Bucket *p;uint nindex;is_consistent (HT); if (Unexpected (ht-> Nnumofelements = = 0) {return SUCCESS;} memset (ht->arbuckets, 0, ht->ntablesize * sizeof (Bucket *));p = Ht->plisthead;while (P! = NULL) {NIndex = P->h & ht->ntablemask; Connect_to_bucket_dllist (P, Ht->arbuckets[nindex]); Ht->arbuckets[nindex] = P;p = P->plistnext;} return SUCCESS;}
By comparison, it is found that the memory and time consumption of ordinary PHP arrays are mostly used on the symbol table compared with fixed arrays. PHP internal implementation of an important idea is to exchange space for time, with Hashtable can quickly locate the elements of the data, it even Hashtable design into a doubly linked list, and because the PHP array space is dynamically allocated, and the interior is implemented in C, C language Array space allocation only fixed allocation, in order to make the user feel that PHP arrays are dynamically allocated space, can only be implemented through resize and rehash, so the fixed array ratio, the same number of elements assigned, time is slow. In short, ordinary arrays and fixed arrays each have advantages and disadvantages, can not say that fixed array time and space consumption is lower, the specific situation needs to take into account the specific business scenarios.