Skip to content

Commit c312294

Browse files
committed
Merge branch 'array_filter-optimize' into HEAD
2 parents 231bc7c + 366713d commit c312294

File tree

1 file changed

+31
-38
lines changed

1 file changed

+31
-38
lines changed

ext/standard/array.c

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4681,15 +4681,15 @@ static int zval_user_compare(zval *a, zval *b) /* {{{ */
46814681

46824682
static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */
46834683
{
4684-
uint32_t idx;
4685-
Bucket *p;
46864684
int argc, i;
46874685
zval *args;
46884686
int (*intersect_data_compare_func)(zval *, zval *) = NULL;
46894687
zend_bool ok;
46904688
zval *val, *data;
46914689
int req_args;
46924690
char *param_spec;
4691+
zend_string *key;
4692+
zend_ulong h;
46934693

46944694
/* Get the argument count */
46954695
argc = ZEND_NUM_ARGS();
@@ -4727,21 +4727,15 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
47274727

47284728
array_init(return_value);
47294729

4730-
for (idx = 0; idx < Z_ARRVAL(args[0])->nNumUsed; idx++) {
4731-
p = Z_ARRVAL(args[0])->arData + idx;
4732-
val = &p->val;
4733-
if (Z_TYPE_P(val) == IS_UNDEF) continue;
4734-
if (UNEXPECTED(Z_TYPE_P(val) == IS_INDIRECT)) {
4735-
val = Z_INDIRECT_P(val);
4736-
if (Z_TYPE_P(val) == IS_UNDEF) continue;
4737-
}
4730+
/* Iterate over keys of the first array (handling possibility of indirects such as in $GLOBALS), to compute keys that are in all of the other arrays. */
4731+
ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL(args[0]), h, key, val) {
47384732
if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
47394733
val = Z_REFVAL_P(val);
47404734
}
4741-
if (p->key == NULL) {
4735+
if (key == NULL) {
47424736
ok = 1;
47434737
for (i = 1; i < argc; i++) {
4744-
if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), p->h)) == NULL ||
4738+
if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), h)) == NULL ||
47454739
(intersect_data_compare_func &&
47464740
intersect_data_compare_func(val, data) != 0)
47474741
) {
@@ -4751,12 +4745,12 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
47514745
}
47524746
if (ok) {
47534747
Z_TRY_ADDREF_P(val);
4754-
zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, val);
4748+
zend_hash_index_add_new(Z_ARRVAL_P(return_value), h, val);
47554749
}
47564750
} else {
47574751
ok = 1;
47584752
for (i = 1; i < argc; i++) {
4759-
if ((data = zend_hash_find_ex_ind(Z_ARRVAL(args[i]), p->key, 1)) == NULL ||
4753+
if ((data = zend_hash_find_ex_ind(Z_ARRVAL(args[i]), key, 1)) == NULL ||
47604754
(intersect_data_compare_func &&
47614755
intersect_data_compare_func(val, data) != 0)
47624756
) {
@@ -4766,10 +4760,10 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
47664760
}
47674761
if (ok) {
47684762
Z_TRY_ADDREF_P(val);
4769-
zend_hash_update(Z_ARRVAL_P(return_value), p->key, val);
4763+
zend_hash_add_new(Z_ARRVAL_P(return_value), key, val);
47704764
}
47714765
}
4772-
}
4766+
} ZEND_HASH_FOREACH_END();
47734767
}
47744768
/* }}} */
47754769

@@ -5097,13 +5091,13 @@ PHP_FUNCTION(array_uintersect_uassoc)
50975091

50985092
static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */
50995093
{
5100-
uint32_t idx;
5101-
Bucket *p;
51025094
int argc, i;
51035095
zval *args;
51045096
int (*diff_data_compare_func)(zval *, zval *) = NULL;
51055097
zend_bool ok;
51065098
zval *val, *data;
5099+
zend_string *key;
5100+
zend_ulong h;
51075101

51085102
/* Get the argument count */
51095103
argc = ZEND_NUM_ARGS();
@@ -5138,21 +5132,15 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
51385132

51395133
array_init(return_value);
51405134

5141-
for (idx = 0; idx < Z_ARRVAL(args[0])->nNumUsed; idx++) {
5142-
p = Z_ARRVAL(args[0])->arData + idx;
5143-
val = &p->val;
5144-
if (Z_TYPE_P(val) == IS_UNDEF) continue;
5145-
if (UNEXPECTED(Z_TYPE_P(val) == IS_INDIRECT)) {
5146-
val = Z_INDIRECT_P(val);
5147-
if (Z_TYPE_P(val) == IS_UNDEF) continue;
5148-
}
5135+
/* Iterate over keys of the first array (handling possibility of indirects such as in $GLOBALS), to compute keys that aren't in the other arrays. */
5136+
ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL(args[0]), h, key, val) {
51495137
if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
51505138
val = Z_REFVAL_P(val);
51515139
}
5152-
if (p->key == NULL) {
5140+
if (key == NULL) {
51535141
ok = 1;
51545142
for (i = 1; i < argc; i++) {
5155-
if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), p->h)) != NULL &&
5143+
if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), h)) != NULL &&
51565144
(!diff_data_compare_func ||
51575145
diff_data_compare_func(val, data) == 0)
51585146
) {
@@ -5162,12 +5150,12 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
51625150
}
51635151
if (ok) {
51645152
Z_TRY_ADDREF_P(val);
5165-
zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, val);
5153+
zend_hash_index_add_new(Z_ARRVAL_P(return_value), h, val);
51665154
}
51675155
} else {
51685156
ok = 1;
51695157
for (i = 1; i < argc; i++) {
5170-
if ((data = zend_hash_find_ex_ind(Z_ARRVAL(args[i]), p->key, 1)) != NULL &&
5158+
if ((data = zend_hash_find_ex_ind(Z_ARRVAL(args[i]), key, 1)) != NULL &&
51715159
(!diff_data_compare_func ||
51725160
diff_data_compare_func(val, data) == 0)
51735161
) {
@@ -5177,10 +5165,10 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
51775165
}
51785166
if (ok) {
51795167
Z_TRY_ADDREF_P(val);
5180-
zend_hash_update(Z_ARRVAL_P(return_value), p->key, val);
5168+
zend_hash_add_new(Z_ARRVAL_P(return_value), key, val);
51815169
}
51825170
}
5183-
}
5171+
} ZEND_HASH_FOREACH_END();
51845172
}
51855173
/* }}} */
51865174

@@ -6103,11 +6091,12 @@ PHP_FUNCTION(array_filter)
61036091
Z_PARAM_LONG(use_type)
61046092
ZEND_PARSE_PARAMETERS_END();
61056093

6106-
array_init(return_value);
61076094
if (zend_hash_num_elements(Z_ARRVAL_P(array)) == 0) {
6095+
RETVAL_EMPTY_ARRAY();
61086096
zend_release_fcall_info_cache(&fci_cache);
61096097
return;
61106098
}
6099+
array_init(return_value);
61116100

61126101
if (ZEND_NUM_ARGS() > 1) {
61136102
have_callback = 1;
@@ -6161,9 +6150,9 @@ PHP_FUNCTION(array_filter)
61616150
}
61626151

61636152
if (string_key) {
6164-
operand = zend_hash_update(Z_ARRVAL_P(return_value), string_key, operand);
6153+
operand = zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, operand);
61656154
} else {
6166-
operand = zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand);
6155+
operand = zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, operand);
61676156
}
61686157
zval_add_ref(operand);
61696158
} ZEND_HASH_FOREACH_END();
@@ -6402,7 +6391,11 @@ PHP_FUNCTION(array_chunk)
64026391
num_in = zend_hash_num_elements(Z_ARRVAL_P(input));
64036392

64046393
if (size > num_in) {
6405-
size = num_in > 0 ? num_in : 1;
6394+
if (num_in == 0) {
6395+
RETVAL_EMPTY_ARRAY();
6396+
return;
6397+
}
6398+
size = num_in;
64066399
}
64076400

64086401
array_init_size(return_value, (uint32_t)(((num_in - 1) / size) + 1));
@@ -6418,9 +6411,9 @@ PHP_FUNCTION(array_chunk)
64186411
/* Add entry to the chunk, preserving keys if necessary. */
64196412
if (preserve_keys) {
64206413
if (str_key) {
6421-
entry = zend_hash_update(Z_ARRVAL(chunk), str_key, entry);
6414+
entry = zend_hash_add_new(Z_ARRVAL(chunk), str_key, entry);
64226415
} else {
6423-
entry = zend_hash_index_update(Z_ARRVAL(chunk), num_key, entry);
6416+
entry = zend_hash_index_add_new(Z_ARRVAL(chunk), num_key, entry);
64246417
}
64256418
} else {
64266419
entry = zend_hash_next_index_insert(Z_ARRVAL(chunk), entry);

0 commit comments

Comments
 (0)