Skip to content

Commit 3ba7c40

Browse files
committed
Allocate array to known size
This avoids multiple reallocation when adding new elements to array
1 parent 9a27456 commit 3ba7c40

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

src/simdjson_bindings.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ extern "C" {
2626
#define zend_string_release_ex(s, persistent) zend_string_release((s))
2727
#endif
2828

29+
#ifndef ZVAL_EMPTY_ARRAY
30+
#define ZVAL_EMPTY_ARRAY(value) array_init(value)
31+
#endif
32+
2933
#define SIMDJSON_DEPTH_CHECK_THRESHOLD 100000
3034

3135
PHP_SIMDJSON_API const char* php_simdjson_error_msg(simdjson_php_error_code error)
@@ -54,6 +58,15 @@ get_key_with_optional_prefix(simdjson::dom::element &doc, std::string_view json_
5458
return doc.at_pointer(std_pointer);
5559
}
5660

61+
/** Init packed array with expected size */
62+
static zend_always_inline zend_array* simdjson_init_packed_array(zval *zv, uint32_t size) {
63+
zend_array *arr;
64+
array_init_size(zv, size);
65+
arr = Z_ARR_P(zv);
66+
zend_hash_real_init_packed(arr);
67+
return arr;
68+
}
69+
5770
static simdjson::error_code
5871
build_parsed_json_cust(simdjson_php_parser* parser, simdjson::dom::element &doc, const char *buf, size_t len, bool realloc_if_needed,
5972
size_t depth = simdjson::DEFAULT_MAX_DEPTH) {
@@ -163,16 +176,13 @@ static simdjson_php_error_code create_array(simdjson::dom::element element, zval
163176
break;
164177
case simdjson::dom::element_type::ARRAY : {
165178
const auto json_array = element.get_array().value_unsafe();
166-
#if PHP_VERSION_ID >= 70300
167179
if (json_array.size() == 0) {
168180
/* Reuse the immutable empty array to save memory */
169181
ZVAL_EMPTY_ARRAY(return_value);
170182
break;
171183
}
172-
#endif
173-
zend_array *arr;
174-
array_init(return_value);
175-
arr = Z_ARR_P(return_value);
184+
185+
zend_array *arr = simdjson_init_packed_array(return_value, json_array.size());
176186

177187
for (simdjson::dom::element child : json_array) {
178188
zval array_element;
@@ -189,15 +199,14 @@ static simdjson_php_error_code create_array(simdjson::dom::element element, zval
189199
}
190200
case simdjson::dom::element_type::OBJECT : {
191201
const auto json_object = element.get_object().value_unsafe();
192-
#if PHP_VERSION_ID >= 70300
193202
if (json_object.size() == 0) {
194203
/* Reuse the immutable empty array to save memory */
195204
ZVAL_EMPTY_ARRAY(return_value);
196205
break;
197206
}
198-
#endif
207+
199208
zend_array *arr;
200-
array_init(return_value);
209+
array_init_size(return_value, json_object.size());
201210
arr = Z_ARR_P(return_value);
202211

203212
for (simdjson::dom::key_value_pair field : json_object) {
@@ -243,16 +252,13 @@ static simdjson_php_error_code create_object(simdjson::dom::element element, zva
243252
break;
244253
case simdjson::dom::element_type::ARRAY : {
245254
const auto json_array = element.get_array().value_unsafe();
246-
#if PHP_VERSION_ID >= 70300
247255
if (json_array.size() == 0) {
248256
/* Reuse the immutable empty array to save memory */
249257
ZVAL_EMPTY_ARRAY(return_value);
250258
return simdjson::SUCCESS;
251259
}
252-
#endif
253-
zend_array *arr;
254-
array_init(return_value);
255-
arr = Z_ARR_P(return_value);
260+
261+
zend_array *arr = simdjson_init_packed_array(return_value, json_array.size());
256262

257263
for (simdjson::dom::element child : json_array) {
258264
zval value;

0 commit comments

Comments
 (0)