Skip to content

Commit baa5319

Browse files
authored
json: Improve performance of php_json_encode_array() for non-hooked fields (#20105)
`tmp` can only ever be non-undef if there's a hooked object property, which is already an `UNEXPECTED()` case. Keep track of whether this case is hit or not to avoid needlessly calling `zval_ptr_dtor()`. For: <?php $len = 0; for ($i = 0; $i < 3_000_000; $i++) { $len += strlen(json_encode(array_fill(0, 20, []))); } var_dump($len); This is ~1.02 faster for a gcc 13.3 release build on a Intel(R) Core(TM) i7-1365U. Benchmark 1: /tmp/bench/before /tmp/bench/test6.php Time (mean ± σ): 762.7 ms ± 3.2 ms [User: 758.5 ms, System: 2.8 ms] Range (min … max): 759.2 ms … 769.3 ms 10 runs Benchmark 2: /tmp/bench/after /tmp/bench/test6.php Time (mean ± σ): 748.3 ms ± 9.0 ms [User: 744.3 ms, System: 3.1 ms] Range (min … max): 740.8 ms … 766.2 ms 10 runs Summary /tmp/bench/after /tmp/bench/test6.php ran 1.02 ± 0.01 times faster than /tmp/bench/before /tmp/bench/test6.php
1 parent 4b2bb20 commit baa5319

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

ext/json/json_encoder.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options,
243243
zend_ulong index;
244244

245245
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) {
246+
bool need_dtor = false;
246247
zval tmp;
247248
ZVAL_UNDEF(&tmp);
248249

@@ -264,6 +265,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options,
264265
if ((prop_info->flags & ZEND_ACC_VIRTUAL) && !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]) {
265266
continue;
266267
}
268+
need_dtor = true;
267269
data = zend_read_property_ex(prop_info->ce, Z_OBJ_P(val), prop_info->name, /* silent */ true, &tmp);
268270
if (EG(exception)) {
269271
PHP_JSON_HASH_UNPROTECT_RECURSION(recursion_rc);
@@ -303,7 +305,9 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options,
303305
zval_ptr_dtor(&tmp);
304306
return FAILURE;
305307
}
306-
zval_ptr_dtor(&tmp);
308+
if (UNEXPECTED(need_dtor)) {
309+
zval_ptr_dtor(&tmp);
310+
}
307311

308312
smart_str_appendc(buf, ',');
309313
} ZEND_HASH_FOREACH_END();

0 commit comments

Comments
 (0)