-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix #75533: array_reduce is slow when $carry is large array #2931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
That doesn't look right ... |
may be |
As long as zend_call_function for the callback function succeeds and doesn't return UNDEF, this PR simply changes the order of processing in the loop. Extracting only the part related to Without this diff: ZVAL_COPY(&args[0], &result);
zend_call_function(&fci, &fci_cache)
zval_ptr_dtor(&args[0]);
zval_ptr_dtor(&result);
ZVAL_COPY_VALUE(&result, &retval); With this diff: ZVAL_COPY(&args[0], &result);
zval_ptr_dtor(&result);
zend_call_function(&fci, &fci_cache)
zval_ptr_dtor(&args[0]);
ZVAL_COPY_VALUE(&result, &retval); At point before The difference is that while executing zend_call_function on the callback function, the reference count of data is one less than that of the original code, thereby aiming at suppressing unwanted copying. After If the callback function fails or returns undef, it enters the else clause. In this case the reference count to the data is one less than that of original code. Since I would like to test about this case, I can not write a php script that goes to the else side. Please tell me if there is any good way. |
Since this patch has moved the timing of zval_ptr_dtor(&result) before calling zend_call_function(), zval_ptr_dtor(&result) which was added to the else clause to fix #76778 is unnecessary.
@@ -5986,15 +5986,15 @@ PHP_FUNCTION(array_reduce) | |||
ZVAL_COPY(&args[1], operand); | |||
fci.params = args; | |||
|
|||
zval_ptr_dtor(&result); | |||
|
|||
if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { | |||
zval_ptr_dtor(&args[1]); | |||
zval_ptr_dtor(&args[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both if
and else
branches have these zval_ptr_dtor(&args[1]);
and zval_ptr_dtor(&args[0]);
lines. Can't we move out of the check to avoid duplication?
Sorry for the delay, merged a slightly simplified form into 7.1+ via ab6c45f. |
Bug #75533
result
is no longer necessary afterZVAL_COPY(&args[0], &result);
, but it keeps references to arrays while executing callback, causing unwanted copying when manipulating arrays in callback. This fix solves this problem by movingzval_ptr_dtor(&result);
beforezend_call_function
.test script (test_array_reduce.php):
Without this fix:
With this fix: