Task #55626
closedReplace GeneralUtility::inList with isset() for lists of values being static or within loops
100%
Description
There are about 250 places in the core making use of GeneralUtility::inList
GeneralUtility::inList('formtype_mail,subject,html_enabled', $confData['fieldname']));
GeneralUtility::inList($listToCheck, $confData['fieldname']));
On the one hand this is quite fast and handy, when you are checking variable lists of values just once.
But while checking variable lists that are used within a loop or static lists of know values, it would be much faster and less memory consuming to make use of an array with appropriate keys and isset();
Just two simple use cases with loops:
$listArrayToCheck = array_flip(explode(',', $listToCheck));
foreach($whatever as $value) {
if(isset($listArrayToCheck[$value])) {}
}
or
$listArrayToCheck = array_flip(array(
'formtype_mail', 'subject', 'html_enabled'
));
foreach($whatever as $value) {
if(isset($listArrayToCheck[$value])) {}
}
would be better than
foreach($whatever as $value) {
GeneralUtility::inList($listToCheck, $value);
}
And a use case for a single check of a known static list:
$listArrayToCheck = array_flip(array(
'formtype_mail', 'subject', 'html_enabled'
));
if(isset($listArrayToCheck[$value]));
So the rule of thumb should be to use GeneralUtility::inList for single checks of lists with unknown values only.
Of course the array_flip could be avoided as well for the use case with known list values, but this would sacrifice readability for performance.
Updated by Markus Klein almost 11 years ago
Corrected the example and added code highlighting
Updated by Mathias Schreiber almost 10 years ago
- Status changed from New to Needs Feedback
- Assignee changed from Jo Hasenau to Mathias Schreiber
Do we have numbers on this?
The numbers would need to be:
Time without isset > (Time for array_flip + Time with isset)
If this is still faster: be my guest :)
Updated by Jo Hasenau almost 10 years ago
Actually it should be
Time for doing strpos for each element in original loop
vs.
Time for flipping exploded list ONCE + doing isset on the generated array for each element in the original loop
Here's a benchmark: http://ryanday.org/index_php.php
The more items to check and/or the longer the list, the stronger the impact.
The memory consumption should be slightly increased though, due to the newly introduced temporary array.
On the other hand we will get back that memory, since we won't call inList anymore.
Updated by Mathias Schreiber almost 10 years ago
All tests run using php version 5.2.4
hmmm
Updated by Jo Hasenau almost 10 years ago
Here's the modified code for testing on different systems using the same "inList" method as the core currently does.
I moved the array_flip into the measuring parts to get correct results including the flipping step.
function inList($list, $item) { return strpos(',' . $list . ',', ',' . $item . ',') !== FALSE; } $letters = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,u,r,s,t,u,v,w,x,y,z'; $letter_array = explode(',', $letters); $t1 = microtime(true); for($i=0;$i<=10000;$i++){ foreach($letter_array as $l){ if(inList($letters,$l)!==false){ } } } $ms1 = (microtime(true)-$t1)*1000; $t2 = microtime(true); for($i=0;$i<=10000;$i++){ foreach($letter_array as $l){ if(in_array($l,$letter_array)){ } } } $ms2 = (microtime(true)-$t2)*1000; $t3 = microtime(true); for($i=0;$i<=10000;$i++){ $letter_assoc = array_flip($letter_array); foreach($letter_array as $l){ if(isset($letter_assoc[$l])){ } } } $ms3 = (microtime(true)-$t3)*1000; $t4 = microtime(true); for($i=0;$i<=10000;$i++){ $letter_assoc = array_flip($letter_array); foreach($letter_array as $l){ if(array_key_exists($l,$letter_assoc)){ } } } $ms4 = (microtime(true)-$t4)*1000; echo "strpos: $ms1 "; echo "in_array: $ms2 "; echo "isset: $ms3 "; echo "array_key_exists: $ms4 ";
Results with PHP 5.4 using PHP tester website:
strpos: 318.2098865509 in_array: 250.89502334595 isset: 52.170991897583 array_key_exists: 89.164018630981
Results with PHP 5.5 using onlinephpfunctions website:
strpos: 228.17492485046 in_array: 197.90005683899 isset: 33.337831497192 array_key_exists: 48.688173294067
These results are just single results, but the difference is big enough to assume, that array_flip + isset will usually win compared to inList.
Updated by Gerrit Code Review over 9 years ago
- Status changed from Needs Feedback to Under Review
Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37136
Updated by Gerrit Code Review over 9 years ago
Patch set 2 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37136
Updated by Markus Klein over 9 years ago
These benchmarks are insufficient IMHO.
We need to know numbers for PHP 5.5 and 5.6. For a fair comparison this needs to compare a inList() call with the full set of calls to trimExplode()+flip+isset.
I really doubt that a simple strpos() can be beat by array magic.
Updated by Gerrit Code Review over 9 years ago
Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37137
Updated by Gerrit Code Review over 9 years ago
Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37138
Updated by Gerrit Code Review over 9 years ago
Patch set 2 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37138
Updated by Gerrit Code Review over 9 years ago
Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37139
Updated by Gerrit Code Review over 9 years ago
Patch set 3 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37136
Updated by Gerrit Code Review over 9 years ago
Patch set 4 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37136
Updated by Gerrit Code Review over 9 years ago
Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37339
Updated by Christian Kuhn over 9 years ago
- Status changed from Under Review to Rejected
Hey. Thanks for patch and analysis, but it seems this one won't make it for the time being. I'll close the issue as rejected for now.
Updated by Stefan Neufeind over 9 years ago
- Status changed from Rejected to Resolved
- Target version changed from 6.2.0 to 7.3 (Packages)
- TYPO3 Version changed from 6.2 to 7
Updated by Stefan Neufeind over 9 years ago
- Status changed from Resolved to Under Review
One was just merged, others still under review.
Updated by Christian Kuhn over 9 years ago
Please do not add several patches for one issue. Please create further issues for other patches an related the issues to each other. I was not aware there are several patches resolving the same issue!
Updated by Stefan Neufeind over 9 years ago
If I remember correctly in the end there were two (and others abandoned), since both targeted other sysexts. In the end imho it wasn't that big so it could have gone into one review - but maybe that was not really obvious in the original review or so which got split up then.
Updated by Jo Hasenau over 9 years ago
The original stuff back then was aimed to be one single patch with lots of changes.
Now the advice was: Although this is actually one task, please split it up into smaller patches, so people can easily review them and decide per patch, if this should make it into the core or not.
Nobody asked for separate issues as well, which is why each patch has been connected to this "umbrella issue".
Updated by Benni Mack over 9 years ago
- Target version changed from 7.3 (Packages) to 7.4 (Backend)
Updated by Susanne Moog over 9 years ago
- Target version changed from 7.4 (Backend) to 7.5
Updated by Gerrit Code Review over 9 years ago
Patch set 2 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37139
Updated by Gerrit Code Review over 9 years ago
Patch set 3 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37139
Updated by Gerrit Code Review over 9 years ago
Patch set 4 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/37139
Updated by Gerrit Code Review almost 9 years ago
Patch set 5 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/37139
Updated by Gerrit Code Review almost 9 years ago
Patch set 6 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/37139
Updated by Jo Hasenau almost 9 years ago
- Status changed from Under Review to Resolved
- % Done changed from 0 to 100
Applied in changeset 61226ff9ed579999541940c96d38544e42dd1e44.