Skip to content

Commit 320ad87

Browse files
committed
Use more compact representation for packed arrays.
Store just an array of zvals without keys. Because of smaller data set, this patch may show performance improvement on some apps and benchmarks that use packed arrays. (~1% on PHP-Parser) The patch has a number of disadvantages: - sapi/phpdbg needs special support for packed arrays (WATCH_ON_BUCKET). - ZEND_HASH_FOREACH_* macros became more expensive (bigger and slower), because they have to support both representations (hash and packed). CLI PHP became 37KB bigger just because of these macros. - zend_hash_sort_ex() may require converting packed arrays to hash. - zend_hash_minmax() prototype was changed to compare only values.
1 parent 3fd322b commit 320ad87

22 files changed

+2519
-1138
lines changed

Zend/zend_gc.c

Lines changed: 245 additions & 125 deletions
Large diffs are not rendered by default.

Zend/zend_generators.c

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -608,28 +608,46 @@ static zend_result zend_generator_get_next_delegated_value(zend_generator *gener
608608
HashTable *ht = Z_ARR(generator->values);
609609
HashPosition pos = Z_FE_POS(generator->values);
610610

611-
Bucket *p;
612-
do {
613-
if (UNEXPECTED(pos >= ht->nNumUsed)) {
614-
/* Reached end of array */
615-
goto failure;
616-
}
611+
if (HT_IS_PACKED(ht)) {
612+
do {
613+
if (UNEXPECTED(pos >= ht->nNumUsed)) {
614+
/* Reached end of array */
615+
goto failure;
616+
}
617617

618-
p = &ht->arData[pos];
619-
value = &p->val;
620-
pos++;
621-
} while (Z_ISUNDEF_P(value));
618+
value = &ht->arPacked[pos];
619+
pos++;
620+
} while (Z_ISUNDEF_P(value));
622621

623-
zval_ptr_dtor(&generator->value);
624-
ZVAL_COPY(&generator->value, value);
622+
zval_ptr_dtor(&generator->value);
623+
ZVAL_COPY(&generator->value, value);
625624

626-
zval_ptr_dtor(&generator->key);
627-
if (p->key) {
628-
ZVAL_STR_COPY(&generator->key, p->key);
625+
zval_ptr_dtor(&generator->key);
626+
ZVAL_LONG(&generator->key, pos - 1);
629627
} else {
630-
ZVAL_LONG(&generator->key, p->h);
631-
}
628+
Bucket *p;
632629

630+
do {
631+
if (UNEXPECTED(pos >= ht->nNumUsed)) {
632+
/* Reached end of array */
633+
goto failure;
634+
}
635+
636+
p = &ht->arData[pos];
637+
value = &p->val;
638+
pos++;
639+
} while (Z_ISUNDEF_P(value));
640+
641+
zval_ptr_dtor(&generator->value);
642+
ZVAL_COPY(&generator->value, value);
643+
644+
zval_ptr_dtor(&generator->key);
645+
if (p->key) {
646+
ZVAL_STR_COPY(&generator->key, p->key);
647+
} else {
648+
ZVAL_LONG(&generator->key, p->h);
649+
}
650+
}
633651
Z_FE_POS(generator->values) = pos;
634652
} else {
635653
zend_object_iterator *iter = (zend_object_iterator *) Z_OBJ(generator->values);

0 commit comments

Comments
 (0)