@@ -312,7 +312,7 @@ static zend_always_inline void simdjson_hash_str_add_or_update(HashTable *ht, co
312
312
zend_ulong h;
313
313
314
314
// Check if array is initialized with proper flags and size
315
- // These checks are removed in production code
315
+ // Note: These assertions are automatically removed in production builds
316
316
ZEND_ASSERT (!(HT_FLAGS (ht) & HASH_FLAG_UNINITIALIZED)); // make sure that hashtable was initialized
317
317
ZEND_ASSERT (!(HT_FLAGS (ht) & HASH_FLAG_PACKED)); // make sure that hashtable is not packed
318
318
ZEND_ASSERT (ht->nNumUsed < ht->nTableSize ); // make sure that we still have space for new elements
@@ -372,6 +372,38 @@ static zend_always_inline void simdjson_add_key_to_symtable(HashTable *ht, const
372
372
#endif // PHP_VERSION_ID >= 80200
373
373
}
374
374
375
+ /* *
376
+ * Optimized function for adding keys to objects with built-in memory management.
377
+ * - Uses interned strings for keys <= 1 byte to reduce memory allocation
378
+ * - Implements version-specific optimizations for PHP 8.3+ and 8.2+
379
+ * - Handles string deduplication for short keys
380
+ */
381
+ static zend_always_inline void simdjson_add_key_to_object (HashTable *ht, const char *str, size_t len, zval *value, HashTable *dedup_key_strings) {
382
+ #if PHP_VERSION_ID >= 80300 // see simdjson_init_object
383
+ if (UNEXPECTED (len <= 1 )) {
384
+ // Use interned string
385
+ zend_string *key = len == 1 ? ZSTR_CHAR ((unsigned char )str[0 ]) : ZSTR_EMPTY_ALLOC ();
386
+ zend_hash_update (ht, key, value);
387
+ } else {
388
+ simdjson_hash_str_add_or_update (ht, str, len, value, dedup_key_strings);
389
+ }
390
+ #else
391
+ zend_string *key;
392
+ if (UNEXPECTED (len <= 1 )) {
393
+ key = len == 1 ? ZSTR_CHAR ((unsigned char )str[0 ]) : ZSTR_EMPTY_ALLOC ();
394
+ } else {
395
+ #if PHP_VERSION_ID >= 80200
396
+ zend_ulong h = zend_inline_hash_func (str, len);
397
+ key = simdjson_dedup_key (dedup_key_strings, str, len, h);
398
+ #else
399
+ key = simdjson_string_init (str, len);
400
+ #endif // PHP_VERSION_ID >= 80200
401
+ }
402
+ zend_hash_update (ht, key, value);
403
+ zend_string_release_ex (key, 0 );
404
+ #endif // PHP_VERSION_ID >= 80300
405
+ }
406
+
375
407
static zend_always_inline void simdjson_set_zval_to_int64 (zval *zv, int64_t value) {
376
408
#if SIZEOF_ZEND_LONG < 8
377
409
if (value != (zend_long)value) {
@@ -509,6 +541,7 @@ static simdjson_php_error_code simdjson_create_object(simdjson::dom::element ele
509
541
case simdjson::dom::element_type::OBJECT : {
510
542
const auto json_object = element.get_object ().value_unsafe ();
511
543
zend_object *obj = simdjson_init_object (return_value, json_object.size ());
544
+ HashTable *ht = zend_std_get_properties (obj);
512
545
513
546
for (simdjson::dom::key_value_pair field : json_object) {
514
547
const char *data = field.key .data ();
@@ -527,21 +560,7 @@ static simdjson_php_error_code simdjson_create_object(simdjson::dom::element ele
527
560
return error;
528
561
}
529
562
530
- /* Add the key to the object */
531
- zend_string *key;
532
- if (UNEXPECTED (size <= 1 )) {
533
- key = size == 1 ? ZSTR_CHAR ((unsigned char )data[0 ]) : ZSTR_EMPTY_ALLOC ();
534
- } else {
535
- #if PHP_VERSION_ID >= 80200
536
- zend_ulong h = zend_inline_hash_func (data, size);
537
- key = simdjson_dedup_key (dedup_key_strings, data, size, h);
538
- #else
539
- key = simdjson_string_init (data, size);
540
- #endif
541
- }
542
-
543
- zend_hash_update (zend_std_get_properties (obj), key, &value);
544
- zend_string_release_ex (key, 0 );
563
+ simdjson_add_key_to_object (ht, data, size, &value, dedup_key_strings);
545
564
}
546
565
break ;
547
566
}
0 commit comments