Skip to content
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

[New rule] Do not use in_array #143

Closed
ihor-sviziev opened this issue Sep 24, 2019 · 11 comments
Closed

[New rule] Do not use in_array #143

ihor-sviziev opened this issue Sep 24, 2019 · 11 comments
Labels
proposal New rule proposal

Comments

@ihor-sviziev
Copy link
Collaborator

Rule

in_array creating performance issue in many places when it used a lot of times.

Reason

Performance diff: https://stackoverflow.com/questions/13483219/what-is-faster-in-array-or-isset

It causes performance issues:

Implementation

@ihor-sviziev ihor-sviziev added the proposal New rule proposal label Sep 24, 2019
@lenaorobei
Copy link
Contributor

I would say even: "Do not use in_array in the loop".
ForeachArrayMergeSniff can be extended and renamed in order to perform this check
https://github.com/magento/magento-coding-standard/blob/develop/Magento2/Sniffs/Performance/ForeachArrayMergeSniff.md

@ihor-sviziev
Copy link
Collaborator Author

I would say even: "Do not use in_array in the loop".
ForeachArrayMergeSniff can be extended and renamed in order to perform this check
https://github.com/magento/magento-coding-standard/blob/develop/Magento2/Sniffs/Performance/ForeachArrayMergeSniff.md

We could start from this.

But actually in most cases it’s quite obvious that it could cause performance issues in a loop, while real performance issues becoming on integration phases, when one method that contains in_array for few elements just called few thousands times. Example related to magento tedious/JShrink#90

@lenaorobei
Copy link
Contributor

The issue was discussed during the magento/architecture#290 and it was decided to not to introduce rule that may cause false-positive findings because its static nature (cannot measure actual performance).

@andrey-legayev
Copy link

Sure, in_array() is a general practice in PHP and typical answer to question "how to kill performance"
Should I revoke my pull requests?

@lenaorobei
Copy link
Contributor

@andrey-legayev you are very welcome to join next public architecture discussion and share your thoughts. We are open to any improvements in case they provide a real value.

@andrey-legayev
Copy link

How to optimize magento2 performance:

  • run profiler
  • look for in_array
  • fix it

This is what I do during last 2 weeks.
How to prevent people not to use in_array() for 2000 elements? sometimes in loop...

@lenaorobei
Copy link
Contributor

I do understand you point and the reason that stays behind the use of in_array in loop.
Coding standard rules perform static file analysis and know nothing about array size. The reason why we closed this issue is because PHP CodeSniffer in not appropriate tool to perform such kind of check.

@buskamuza
Copy link

@andrey-legayev , I'd better promote better practices of using loops in general. There are many things that can kill performance, and in_array() is not the only one. IMO, a real human (developer) should think about performant implementation of loops. A general rule is usually:

  • remove anything repeatable outside of a loop

This is not about in_array() calls, and it's hard to cover all use cases with static checks. For example, retrieving value from another service. Anything that doesn't rely on the array item we are iterating, should be move outside of the loop.

In the same time if you have an array of two items you're iterating through, and you do in_array() for another array of three items, most likely you don't care about performance here. And if in_array() adds readability, I'd rather keep it there.

@andrey-legayev
Copy link

I measured in_array() performance for 1 element and isset() is still be faster.
Sure, I had to run code 100k times to see time difference, but if you use it in some base class of framework for.. readability? and then call it through 20 lines of call stack 200k times. Does it make sense? IMO not.
But feel free to use it for readability.

@andrey-legayev
Copy link

For example:
Magento\Framework\Module\ModuleList::sortBySequence()
I'm sure in_array() is used inside double loop for readability. Performance isn't needed there, readability is better.

@lenaorobei
Copy link
Contributor

lenaorobei commented Sep 25, 2019

@andrey-legayev I'm afraid, we are talking about different things there. Let me try to explain. There are two statements we are trying to mix:

  • in_array in loop causes performance issues. Indeed, issues that you provided need to be fixed, there is no discussion regarding this and no objections. Hope, we are on the same page regarding this.
  • Static check for the in_array in loop detection. Current issue proposes to implement PHP CodeSniffer rule for in_array in loop detection. And here we have contra-versional thoughts, because static detection uses tokens and cannot detect performance issue.

That's why it was proposed to investigate and find more appropriate tool for such check.

@andrey-legayev andrey-legayev changed the title [New rule] Do not use in_array b[New rule] Do not use in_array Sep 25, 2019
@andrey-legayev andrey-legayev changed the title b[New rule] Do not use in_array [New rule] Do not use in_array Sep 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal New rule proposal
Projects
None yet
Development

No branches or pull requests

4 participants