Project

General

Profile

Actions

Task #55626

closed

Replace GeneralUtility::inList with isset() for lists of values being static or within loops

Added by Jo Hasenau almost 11 years ago. Updated about 6 years ago.

Status:
Closed
Priority:
Must have
Category:
Performance
Target version:
-
Start date:
2014-02-03
Due date:
% Done:

100%

Estimated time:
TYPO3 Version:
7
PHP Version:
5.4
Tags:
Complexity:
Sprint Focus:

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.


Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Bug #72818: External links including ".php" rendered without httpClosedMarkus Klein2016-01-19

Actions
Actions #1

Updated by Markus Klein almost 11 years ago

Corrected the example and added code highlighting

Actions #2

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 :)

Actions #3

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.

Actions #4

Updated by Mathias Schreiber almost 10 years ago

All tests run using php version 5.2.4

hmmm

Actions #5

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.

Actions #6

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

Actions #7

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

Actions #8

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.

Actions #9

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

Actions #10

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

Actions #11

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

Actions #12

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

Actions #13

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

Actions #14

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

Actions #15

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

Actions #16

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.

Actions #17

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
Actions #18

Updated by Stefan Neufeind over 9 years ago

  • Status changed from Resolved to Under Review

One was just merged, others still under review.

Actions #19

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!

Actions #20

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.

Actions #21

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".

Actions #22

Updated by Benni Mack over 9 years ago

  • Target version changed from 7.3 (Packages) to 7.4 (Backend)
Actions #23

Updated by Susanne Moog over 9 years ago

  • Target version changed from 7.4 (Backend) to 7.5
Actions #24

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

Actions #25

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

Actions #26

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

Actions #27

Updated by Benni Mack about 9 years ago

  • Target version deleted (7.5)
Actions #28

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

Actions #29

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

Actions #30

Updated by Jo Hasenau almost 9 years ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100
Actions #31

Updated by Benni Mack about 6 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF