Skip to content

Constant expressions are not optimized under some conditions #10729

@mvorisek

Description

@mvorisek
Contributor

Description

The following code:

https://3v4l.org/Btrh0/rfc#vgit.master_jit

Resulted in this output:

float(0.1064751148223877)
float(0.07117080688476562)
float(0.3041820526123047)

But I expected this output instead:

float(0.1064751148223877)
float(0.07117080688476562)
float(0.07117080688476562)

I expect array_keys to be optimized to const with const input. 2nd and 3rn time must be about the same.

I also expect in_array to be optimized to use hash based 0(1) lookup when the array is const.

PHP Version

any

Operating System

any

Activity

nielsdos

nielsdos commented on Feb 28, 2023

@nielsdos
Member

There are many things that could in theory be constant-evaluated at compile time. The question is whether those cases are common enough to justify special-casing a constant-evaluation path for them. Tbh, I'm not convinced a function like this is a bottleneck in real-world applications.

mvorisek

mvorisek commented on Feb 28, 2023

@mvorisek
ContributorAuthor

array_keys is pure function, for I would say every pure function can and should be evaluated only once* if the args are const

* at compile time or on the 1st use, at least with JIT

Girgias

Girgias commented on Mar 3, 2023

@Girgias
Member

That's not a bug, what you are asking for is an optimizer feature, and a quite complicated one on top.

mvorisek

mvorisek commented on Mar 3, 2023

@mvorisek
ContributorAuthor

@Girgias why is array_keys complicated to implement? It should be not hard, const. array is accepted, transformed and stored.

nielsdos

nielsdos commented on Mar 3, 2023

@nielsdos
Member

If it's so simple, why don't you try it yourself and see that it's more complicated than you think ;)

mvorisek

mvorisek commented on Mar 3, 2023

@mvorisek
ContributorAuthor

I am not familiar with all the php-src internals, that's why I opened this issue instead of proposing a PR directly. Maybe it is complicated, what are the challenges?

Girgias

Girgias commented on Mar 3, 2023

@Girgias
Member

@Girgias why is array_keys complicated to implement? It should be not hard, const. array is accepted, transformed and stored.

Do not evaluate the complexity of a feature when you have literally no idea what is involved in making this feature happen.
If it's so easy, why don't you do it? Why don't you generalize it to all internal pure functions, and why don't you generalize it to all known pure userland functions?

If you actually thought it was that easy, you would have gone and tried to create this feature yourself via a PR and realize the complexity. Asking other peoples to do it under the purview of you not knowing php-src internals shows a lack of wanting to learn and wasting maintainers time needing to reply to you.

I would urge you to reconsider your interactions with the project as you comment on PRs and act like a maintainer when you are clearly not, and you do not have the knowledge required (proven here by your questions and widely wrong assessments). Moreover, opening draft PRs to attempt to fix bugs just to put a review comment which basically summarizes to "how do I fix this bug", and outright ignoring review comments from actual maintainers because you disagree with them just to harass them afterwards to merge your PR has given you a notoriously bad reputation within the project.

You do provide useful contribution at times, and we appreciate it. However, more often than not, what you are doing is just noise and a waste of time for us to deal with when we could be doing something else. So think twice (or even thrice) before opening an issue, commenting a PR, or generally just interacting with the project.

bwoebi

bwoebi commented on Mar 3, 2023

@bwoebi
Member

@Girgias Thanks for putting it on point.

mvorisek

mvorisek commented on Mar 3, 2023

@mvorisek
ContributorAuthor

@Girgias at least before https://github.com/php/php-src/pull/7780/files#diff-8a2df74d9492ec07c0c953e243b3592538d3a46c9861bffd35dd6500300d8117L813 PR array_keys and array_key_exists functions were present as a functions supporting CTE. I would expect php to eval such functions only once if the args are const. This is why I opened this issue.

KapitanOczywisty

KapitanOczywisty commented on Mar 3, 2023

@KapitanOczywisty

@Girgias at least before https://github.com/php/php-src/pull/7780/files#diff-8a2df74d9492ec07c0c953e243b3592538d3a46c9861bffd35dd6500300d8117L813 PR array_keys and array_key_exists functions were present as a functions supporting CTE.

PR changed only how CTE functions are defined, both array_keys and array_key_exists are still supported for CTE. Have you measured performance in version before that PR? Also I don't know if variable argument can be treated as constant.

mvorisek

mvorisek commented on Mar 3, 2023

@mvorisek
ContributorAuthor

Yes, I fully understand the PR. My expectation is the following - optimizer tracks what variables are const and if a function is marked as CTE and the parameters are const, function is evaluated at compile time *. With the repro code it is not the case. And I wonder why.

In the repro code I measured time with JIT enabled, and even JIT seems to evaluate functions marked as CTE multiple times, so I belive there is some problem.

nielsdos

nielsdos commented on Mar 3, 2023

@nielsdos
Member

A variable (CV) and a const are 2 different things.

mvorisek

mvorisek commented on Mar 3, 2023

@mvorisek
ContributorAuthor

With data defined as const the performance is the same - https://3v4l.org/0ctrZ/rfc#vgit.master_jit . So why CTE function with const input is not evaluated at CT?

nikic

nikic commented on Mar 3, 2023

@nikic
Member

It's not possible to perform optimizations based on global constants (due to constant redeclaration) or based on global variables (due to various issues, including dtor effects). This optimization does work fine inside functions.

mvorisek

mvorisek commented on Mar 3, 2023

@mvorisek
ContributorAuthor

In https://3v4l.org/KoYgs/rfc#vgit.master_jit I have expanded everything. The expressions depend on nothing (they depend only on scalars and inner CTE nodes). All 3 function have constant result. No params accepted/passed. Opcache is enabled with the default optimization level. Each function should (after CTE optimization) consist of the same const value return. Each function time should be therefore about the same. Why they differ?

https://3v4l.org/NnceD/rfc#vgit.master_jit here is simplified repro with 10x same const expr, if the expr would be evaluated at CT, the time should be almost the same - not ~40ms vs 250ms

nikic

nikic commented on Mar 3, 2023

@nikic
Member

I don't know what is happening on 3v4l, but locally this does optimize. That is, a and c are fast, while b is slow because array_fill is not evaluated at compile-time. I also checked the opcodes and the calls are optimized to "return true", as expected.

changed the title [-]`array_keys` with const input seems to be not optimized[/-] [+]Constant expressions are not optimized under some conditions[/+] on Mar 3, 2023
mvorisek

mvorisek commented on Mar 3, 2023

@mvorisek
ContributorAuthor

I don't know what is happening on 3v4l, but locally this does optimize.

Thank you for your reply, I will try to figure this out into a repro steps. Please keep this issue open. I have updated the title to be more precise.

while b is slow because array_fill is not evaluated at compile-time

Also while reviewing 32e2d97 I found out basic functions like array_key_exists (maybe this is fine, it has special handler) and like array_is_list were previously present in can_ct_eval_func_call but newly https://github.com/php/php-src/blob/d5c649b36b/Zend/Optimizer/sccp.c#L752 and https://github.com/php/php-src/blob/d5c649b36b/ext/standard/basic_functions.stub.php#L1862 -> https://github.com/php/php-src/blob/d5c649b36b/ext/standard/basic_functions_arginfo.h#L2927 they are not present anymore. Is PR welcomed?

nikic

nikic commented on Mar 3, 2023

@nikic
Member

while b is slow because array_fill is not evaluated at compile-time

Also while reviewing 32e2d97 I found out basic functions like array_key_exists (maybe this is fine, it has special handler) and like array_is_list were previously present in can_ct_eval_func_call but newly https://github.com/php/php-src/blob/d5c649b36b/Zend/Optimizer/sccp.c#L752 and https://github.com/php/php-src/blob/d5c649b36b/ext/standard/basic_functions.stub.php#L1862 -> https://github.com/php/php-src/blob/d5c649b36b/ext/standard/basic_functions_arginfo.h#L2927 they are not present anymore. Is PR welcomed?

Definitely. As you say, array_key_exists doesn't really matter, but array_is_list is certainly safe to evaluate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @nikic@mvorisek@bwoebi@nielsdos@Girgias

        Issue actions

          Constant expressions are not optimized under some conditions · Issue #10729 · php/php-src