Skip to content

Commit 3507274

Browse files
committed
decoder: Optimise creating arrays
1 parent 3d0dbf0 commit 3507274

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

src/simdjson_decoder.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,42 @@ static zend_always_inline zend_object* simdjson_init_object(zval *zv, uint32_t s
7373
}
7474

7575
/** Init packed array with expected size */
76-
static zend_always_inline zend_array* simdjson_init_packed_array(zval *zv, uint32_t size) {
77-
zend_array *arr;
78-
array_init_size(zv, size);
79-
arr = Z_ARR_P(zv);
80-
zend_hash_real_init_packed(arr);
81-
return arr;
76+
static zend_always_inline HashTable* simdjson_init_packed_array(zval *zv, uint32_t size) {
77+
HashTable *ht;
78+
void *data;
79+
80+
ht = zend_new_array(size);
81+
82+
#if PHP_VERSION_ID >= 80200
83+
// Can be replaced with zend_hash_real_init_packed, but this removes some unnecessary checks
84+
if (EXPECTED(ht->nTableSize == HT_MIN_SIZE)) {
85+
/* Use specialized API with constant allocation amount for a particularly common case. */
86+
data = emalloc(HT_PACKED_SIZE_EX(HT_MIN_SIZE, HT_MIN_MASK));
87+
} else {
88+
data = emalloc(HT_PACKED_SIZE_EX(ht->nTableSize, HT_MIN_MASK));
89+
}
90+
HT_SET_DATA_ADDR(ht, data);
91+
ht->u.v.flags = HASH_FLAG_PACKED | HASH_FLAG_STATIC_KEYS;
92+
HT_HASH_RESET_PACKED(ht);
93+
#else
94+
zend_hash_real_init_packed(ht);
95+
#endif
96+
97+
ZVAL_ARR(zv, ht);
98+
99+
return ht;
100+
}
101+
102+
/** Initialize mixed array with exact size (in PHP terminology mixed array is hash) */
103+
static zend_always_inline HashTable* simdjson_init_mixed_array(zval *zv, uint32_t size) {
104+
HashTable *ht;
105+
106+
ht = zend_new_array(size);
107+
#if PHP_VERSION_ID >= 80200
108+
zend_hash_real_init_mixed(ht); // Expect mixed array
109+
#endif
110+
ZVAL_ARR(zv, ht);
111+
return ht;
82112
}
83113

84114
/** Check if it is necessary to reallocate string to buffer */
@@ -279,17 +309,6 @@ static zend_always_inline void simdjson_zend_hash_str_add_or_update(HashTable *h
279309
}
280310
#endif // PHP_VERSION_ID >= 80200
281311

282-
// Initialize mixed array with exact size (in PHP terminology mixed array is hash)
283-
static zend_always_inline HashTable* simdjson_init_mixed_array(zval *zv, uint32_t size) {
284-
HashTable *ht;
285-
array_init_size(zv, size);
286-
ht = Z_ARR_P(zv);
287-
#if PHP_VERSION_ID >= 80200
288-
zend_hash_real_init_mixed(ht); // Expect mixed array
289-
#endif
290-
return ht;
291-
}
292-
293312
static zend_always_inline void simdjson_add_key_to_symtable(HashTable *ht, const char *buf, size_t len, zval *value, HashTable *repeated_key_strings) {
294313
#if PHP_VERSION_ID >= 80200
295314
zend_ulong idx;

0 commit comments

Comments
 (0)