Home  >  Article  >  Backend Development  >  PHP source code array statistics count analysis_PHP tutorial

PHP source code array statistics count analysis_PHP tutorial

WBOY
WBOYOriginal
2016-07-21 15:25:43744browse

All variables given to PHP by zend are saved in a structural way, and the saving of strings and the saving of arrays are also different. Arrays are saved in the form of hash tables (everyone knows that the address saved by hash can effectively reduce conflicts -hash You know the concept of hash tables), and the structure in php is as follows:

Copy code The code is as follows:

//File 1: zend/zend.h
/*
* zval
*/
typedef struct _zval_struct zval;
...
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;

struct _zval_struct {
/* Variable information */
zvalue_value value; /* value * /
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
//The structure of the hash table is as follows
//File 2: zend/ zend_hash.h
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_DEBUG
int inconsistent;
#endif
}
HashTable;

When a general variable (string) uses strlen to get the length, what is actually obtained is The len attribute in the zvalue_value.str structure is efficient in O(1) times. A special point to note is that strlen does not have a core implementation in php, but uses the macro definition in zend to obtain it:


Copy code The code is as follows:
//File 3: zend/zend_operators.php
#define Z_STRLEN(zval ) (zval).value.str.len
...
#define Z_STRLEN_P(zval_p) Z_STRLEN(*zval_p)
...
#define Z_STRLEN_PP(zval_pp) Z_STRLEN(**zval_pp )

As for the count operation of the array, there are actually two results. The second parameter mode is also mentioned in the count API "http://www.php.net/manual/en /function.count.php》, this mode parameter indicates whether re-counting is required, and its re-counting will traverse the array once, and the efficiency is O(N)[N: length]. By default, no re-counting is required. , then nNumOfElements in the hashtable will be output directly at this time, and the efficiency at this time is also O(1) times: the count code is as follows:

Copy code The code is as follows :
//File 4: ext/standard/array.c
PHP_FUNCTION(count)
{
zval *array;
long mode = COUNT_NORMAL;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &array, &mode) == FAILURE) {
return;
}

switch (Z_TYPE_P(array)) {
case IS_NULL:
RETURN_LONG(0);
break;
case IS_ARRAY:
RETURN_LONG (php_count_recursive (array, mode TSRMLS_CC));
break;
.. ...

//Implementation of php_count_recursive
static int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */
{
long cnt = 0;
zval **element;

if (Z_TYPE_P(array) == IS_ARRAY) {
//Error handling
if (Z_ARRVAL_P(array)->nApplyCount > 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
return 0;
}
//Get the length directly through zend_hash_num_elements
cnt = zend_hash_num_elements(Z_ARRVAL_P(array));

//If it is specified that re-counting is required, it will enter a cycle of statistics
if (mode == COUNT_RECURSIVE) {
HashPosition pos;

for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **) &element, &pos) == SUCCESS;
zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos)
) {
Z_ARRVAL_P(array) ->nApplyCount++;
cnt += php_count_recursive(*element, COUNT_RECURSIVE TSRMLS_CC);
Z_ARRVAL_P(array)->nApplyCount--;
}
}
}

return cnt;
}

//File 5: zend/zend_hash.c
//Implementation of zend_hash_num_elements
ZEND_API int zend_hash_num_elements(const HashTable *ht)
{
IS_CONSISTENT(ht);

return ht->nNumOfElements;
}

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/324079.htmlTechArticleAll variables given by zend to PHP are saved in the form of structures, and strings and arrays are also saved. Differently, the array is stored in a hash table (everyone knows that hash storage...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn