From 97a241b2ec1941005e6d5b91c73a1773654de1bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 7 Oct 2025 12:09:34 +0200 Subject: [PATCH 1/2] json: Improve performance of `php_json_encode_array()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of using a boolean flag to check for each element whether or not it is the first, we just unconditionally append a comma after each element and then remove the last comma at the end. For: s)[ZSTR_LEN(buf->s) - 1] != ','; + if (!empty) { + /* Drop the trailing comma. */ + ZSTR_LEN(buf->s)--; } PHP_JSON_HASH_UNPROTECT_RECURSION(obj); @@ -197,7 +198,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, } --encoder->depth; - if (need_comma) { + if (!empty) { php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); } @@ -235,6 +236,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, uint32_t i = myht ? zend_hash_num_elements(myht) : 0; + bool empty = true; if (i > 0) { zend_string *key; zval *data; @@ -247,12 +249,6 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, if (!encode_as_object) { ZEND_ASSERT(Z_TYPE_P(data) != IS_PTR); - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = true; - } - php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); } else { @@ -276,11 +272,6 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, } } - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = true; - } php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); @@ -293,12 +284,6 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, smart_str_appendl(buf, "\"\"", 2); } } else { - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = true; - } - php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); @@ -319,7 +304,15 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, return FAILURE; } zval_ptr_dtor(&tmp); + + smart_str_appendc(buf, ','); } ZEND_HASH_FOREACH_END(); + + empty = ZSTR_VAL(buf->s)[ZSTR_LEN(buf->s) - 1] != ','; + if (!empty) { + /* Drop the trailing comma. */ + ZSTR_LEN(buf->s)--; + } } PHP_JSON_HASH_UNPROTECT_RECURSION(recursion_rc); @@ -334,7 +327,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, --encoder->depth; /* Only keep closing bracket on same line for empty arrays/objects */ - if (need_comma) { + if (!empty) { php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); } From 77ec141502ad3a4e4f54fe6fc8149284099e53bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 8 Oct 2025 08:46:10 +0200 Subject: [PATCH 2/2] UPGRADING --- UPGRADING | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UPGRADING b/UPGRADING index 334c0fc6bdac3..51a057003b544 100644 --- a/UPGRADING +++ b/UPGRADING @@ -84,3 +84,6 @@ PHP 8.6 UPGRADE NOTES ======================================== 14. Performance Improvements ======================================== + +- JSON: + . Improve performance of encoding arrays and objects.