Skip to content

Commit 0697d83

Browse files
committed
More straightforward count() on ArrayObject with object
Just writing this out as an explicit loop is both simpler and faster than going through the entire positioning machinery.
1 parent 5659035 commit 0697d83

File tree

1 file changed

+17
-21
lines changed

1 file changed

+17
-21
lines changed

ext/spl/spl_array.c

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,26 +1368,24 @@ SPL_METHOD(Array, seek)
13681368
zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Seek position " ZEND_LONG_FMT " is out of range", opos);
13691369
} /* }}} */
13701370

1371-
static int spl_array_object_count_elements_helper(spl_array_object *intern, zend_long *count) /* {{{ */
1371+
static zend_long spl_array_object_count_elements_helper(spl_array_object *intern) /* {{{ */
13721372
{
13731373
HashTable *aht = spl_array_get_hash_table(intern);
1374-
HashPosition pos, *pos_ptr;
1375-
13761374
if (spl_array_is_object(intern)) {
1377-
/* We need to store the 'pos' since we'll modify it in the functions
1378-
* we're going to call and which do not support 'pos' as parameter. */
1379-
pos_ptr = spl_array_get_pos_ptr(aht, intern);
1380-
pos = *pos_ptr;
1381-
*count = 0;
1382-
spl_array_rewind(intern);
1383-
while (*pos_ptr < aht->nNumUsed && spl_array_next(intern) == SUCCESS) {
1384-
(*count)++;
1385-
}
1386-
*pos_ptr = pos;
1387-
return SUCCESS;
1375+
zend_long count = 0;
1376+
zend_string *key;
1377+
zval *val;
1378+
/* Count public/dynamic properties */
1379+
ZEND_HASH_FOREACH_STR_KEY_VAL(aht, key, val) {
1380+
if (Z_TYPE_P(val) == IS_INDIRECT) {
1381+
if (Z_TYPE_P(Z_INDIRECT_P(val)) == IS_UNDEF) continue;
1382+
if (key && ZSTR_VAL(key)[0] == '\0') continue;
1383+
}
1384+
count++;
1385+
} ZEND_HASH_FOREACH_END();
1386+
return count;
13881387
} else {
1389-
*count = zend_hash_num_elements(aht);
1390-
return SUCCESS;
1388+
return zend_hash_num_elements(aht);
13911389
}
13921390
} /* }}} */
13931391

@@ -1406,24 +1404,22 @@ int spl_array_object_count_elements(zval *object, zend_long *count) /* {{{ */
14061404
*count = 0;
14071405
return FAILURE;
14081406
}
1409-
return spl_array_object_count_elements_helper(intern, count);
1407+
*count = spl_array_object_count_elements_helper(intern);
1408+
return SUCCESS;
14101409
} /* }}} */
14111410

14121411
/* {{{ proto int ArrayObject::count()
14131412
proto int ArrayIterator::count()
14141413
Return the number of elements in the Iterator. */
14151414
SPL_METHOD(Array, count)
14161415
{
1417-
zend_long count;
14181416
spl_array_object *intern = Z_SPLARRAY_P(getThis());
14191417

14201418
if (zend_parse_parameters_none() == FAILURE) {
14211419
return;
14221420
}
14231421

1424-
spl_array_object_count_elements_helper(intern, &count);
1425-
1426-
RETURN_LONG(count);
1422+
RETURN_LONG(spl_array_object_count_elements_helper(intern));
14271423
} /* }}} */
14281424

14291425
static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fname_len, int use_arg) /* {{{ */

0 commit comments

Comments
 (0)