Feature #88754
closedCodesmell GeneralUtility::trimExplode()
Added by Dieter Porth over 5 years ago. Updated over 5 years ago.
0%
Description
Optimize Coding of GeneralUtility:trimExplode. The Foreach-loop and the slice-Operation seems not good in the current method.
I guess, the following-code is faster.
public static function trimExplode($delim, $string, $removeEmptyValues = false, $limit = 0) { if ($limit>0) { $result = array_map('trim', explode($delim, $string,$limit)); } else { $result = array_map('trim', explode($delim, $string)); } if ($removeEmptyValues === true) { $result = array_filter($result, function($k){ return $k !== '' }); } return $result; }
The code-example and the performance is not tested yet.
Perhaps: If the $removeEmptyValues ist related to the php-Function empty(), then the filter-function is obsolete. $result = array_filter($result)
Updated by Benni Mack over 5 years ago
- Status changed from New to Needs Feedback
It would be very interesting to see if it is actually faster.
using tools like "phpbench" would help us here. Care to give it a try to see before/after information?
Updated by Frank Nägler over 5 years ago
The following bench results are from a quick phpbench check.
Old means the existing method
new means the method of this issue
All runs started with a string containing 1000 entries, also duplicates.
Thew runs 3+4 (...RemoveEmpty) are using the third parameter "removeEmptyValues".
The fourth parameter limit and more combinations of arguments were not tested yet.
\TrimExplodeBench benchOld I0 P0 [μ Mo]/r: 613.259 613.259 (μs) [μSD μRSD]/r: 0.000μs 0.00% benchNew I0 P0 [μ Mo]/r: 570.521 570.521 (μs) [μSD μRSD]/r: 0.000μs 0.00% benchOldRemoveEmpty I0 P0 [μ Mo]/r: 1,330.770 1,330.770 (μs) [μSD μRSD]/r: 0.000μs 0.00% benchNewRemoveEmpty I0 P0 [μ Mo]/r: 2,591.502 2,591.502 (μs) [μSD μRSD]/r: 0.000μs 0.00% 4 subjects, 4 iterations, 4,000 revs, 0 rejects, 0 failures, 0 warnings (best [mean mode] worst) = 570.521 [1,276.513 1,276.513] 570.521 (μs) ⅀T: 5,106.052μs μSD/r 0.000μs μRSD/r: 0.000%
Updated by Frank Nägler over 5 years ago
The bench class
<?php include 'typo3/sysext/core/Classes/Utility/GeneralUtility.php'; class TrimExplodeBench { static $string = '1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,'; /** * @Revs({1000}) */ public function benchOld() { \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', self::$string, false); } /** * @Revs({1000}) */ public function benchNew() { \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplodeNew(',', self::$string, false); } /** * @Revs({1000}) */ public function benchOldRemoveEmpty() { \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', self::$string, true); } /** * @Revs({1000}) */ public function benchNewRemoveEmpty() { \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplodeNew(',', self::$string, true); } }
Updated by Oliver Hader over 5 years ago
Thx, I've adjusted implementation a litte bit and added 5 iterations, keeping 1000 revolutions.
Test have been executed in CLI mode, having opCache enabled. Tests are organized in groups to determine proper difference and std deviation.
String, 1000 numerics, no spaces or empty items (like shown before)¶
static $string = '1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,';
+------------------+-----------------------------+-----+------+-----+----------+-----------+-----------+-----------+-----------+----------+--------+-------+ | benchmark | subject | set | revs | its | mem_peak | best | mean | mode | worst | stdev | rstdev | diff | +------------------+-----------------------------+-----+------+-----+----------+-----------+-----------+-----------+-----------+----------+--------+-------+ | TrimExplodeBench | bench_trimExplode_old | 0 | 1000 | 5 | 513,456b | 501.934μs | 516.467μs | 513.863μs | 533.355μs | 11.068μs | 2.14% | 1.00x | | TrimExplodeBench | bench_trimExplode_candidate | 0 | 1000 | 5 | 513,464b | 511.662μs | 535.493μs | 527.610μs | 572.027μs | 20.160μs | 3.76% | 1.04x | +------------------+-----------------------------+-----+------+-----+----------+-----------+-----------+-----------+-----------+----------+--------+-------+
New candidate seems to be a litte bit slower, but still "almost equal".
+------------------+-----------------------------------------------+-----+------+-----+----------+-------------+-------------+-------------+-------------+----------+--------+-------+ | benchmark | subject | set | revs | its | mem_peak | best | mean | mode | worst | stdev | rstdev | diff | +------------------+-----------------------------------------------+-----+------+-----+----------+-------------+-------------+-------------+-------------+----------+--------+-------+ | TrimExplodeBench | bench_trimExplode_old_removeEmptyValues | 0 | 1000 | 5 | 513,472b | 1,158.088μs | 1,186.733μs | 1,174.369μs | 1,225.729μs | 24.106μs | 2.03% | 1.00x | | TrimExplodeBench | bench_trimExplode_candidate_removeEmptyValues | 0 | 1000 | 5 | 513,808b | 1,583.447μs | 1,630.353μs | 1,607.766μs | 1,717.071μs | 47.140μs | 2.89% | 1.37x | +------------------+-----------------------------------------------+-----+------+-----+----------+-------------+-------------+-------------+-------------+----------+--------+-------+
New candidate seems to be slower.
String, 1000 alpha-numerics, all wrapped by spaces, random number of empty items¶
static $string = ' , 9 , 7 , m , 61 , 46 , 75 , i , 58 , 93 , 41 , 55 , 68 , 26 , 72 , 9 , 2 , 0 , 32 , g , s , , 75 , 4 , , i , 78 , p , r , a , v , x , 27 , 60 , 54 , 91 , 91 , 78 , 71 , 62 , o , 17 , 56 , 72 , 91 , 78 , d , 13 , c , 52 , 27 , 22 , 12 , 60 , 100 , 15 , 38 , 11 , 81 , 28 , 82 , 18 , 22 , 74 , s , 73 , 17 , 74 , 70 , 22 , 22 , 85 , 21 , 37 , 20 , 9 , 46 , , , 3 , 32 , , 3 , d , 78 , 63 , 22 , , 82 , 91 , 97 , 69 , 46 , 74 , u , 20 , 66 , 13 , b , 30 , h , 59 , 21 , 0 , v , 82 , , 92 , 80 , 68 , r , 72 , 40 , x , n , 1 , 49 , 56 , 82 , 12 , 42 , 28 , t , 87 , 61 , 37 , 75 , 38 , c , 77 , 88 , h , 95 , , 34 , 82 , m , , u , 87 , 16 , 64 , 87 , 51 , w , 1 , , 50 , 35 , 21 , 93 , 13 , 14 , 66 , 45 , z , k , 6 , z , 39 , 54 , 7 , d , 71 , 12 , e , 77 , 70 , 71 , i , 69 , g , 97 , 48 , 47 , 0 , e , , , 44 , 40 , 54 , 76 , 52 , 78 , 85 , , 90 , 57 , 96 , 99 , 44 , 79 , 60 , x , 22 , 59 , o , k , 4 , h , h , 8 , 50 , u , , c , 56 , 94 , v , 75 , 93 , 58 , r , 62 , 14 , 48 , 35 , , z , 45 , 13 , 40 , x , 57 , 0 , 73 , 22 , 34 , 41 , 73 , 35 , 20 , 23 , l , r , k , 86 , 17 , , , b , 77 , 11 , 90 , 2 , 12 , 35 , 36 , 40 , 87 , , u , 52 , 57 , 3 , , 48 , 47 , 12 , 50 , g , 95 , 13 , , n , 15 , 41 , 32 , 88 , 84 , 49 , 2 , 77 , 59 , , , 12 , c , 6 , 4 , c , 45 , 62 , , 41 , 82 , 3 , 97 , , f , 5 , 64 , , 60 , 35 , 59 , 57 , , 66 , 52 , 56 , 39 , z , r , 37 , 52 , 77 , 96 , 71 , 99 , 9 , 29 , 21 , 53 , s , 7 , 97 , 8 , 82 , 81 , q , 88 , 12 , 55 , 53 , c , v , 99 , 22 , 35 , 50 , 92 , 21 , 16 , a , 78 , k , v , 74 , 14 , 45 , 93 , 82 , l , 9 , w , 44 , 27 , , 4 , 96 , v , 15 , , 30 , 99 , 58 , 61 , x , 91 , q , 97 , u , z , 18 , 65 , 88 , 55 , 59 , 19 , 7 , h , 87 , 9 , 86 , , , u , 16 , 13 , 93 , 37 , h , , , 2 , 66 , n , 89 , 17 , 50 , b , 32 , 9 , p , 13 , 15 , x , 89 , 64 , 73 , 77 , y , 42 , , 65 , p , e , t , 15 , 62 , 66 , 91 , 24 , 54 , 4 , p , 28 , 80 , m , 45 , , 27 , 72 , 77 , 39 , 77 , , 33 , 63 , 60 , 17 , 53 , 20 , 72 , 59 , r , w , 99 , c , , 14 , 79 , 85 , s , 59 , 21 , 58 , 23 , 67 , , 70 , d , 22 , 66 , f , 4 , 19 , 86 , 9 , 12 , 63 , 77 , 58 , 2 , h , 21 , 22 , 70 , 70 , 100 , t , m , 67 , j , 77 , f , 59 , 44 , j , 10 , h , 97 , , 14 , 89 , , 53 , 79 , 26 , 28 , m , q , 64 , n , 82 , 41 , 100 , 100 , 30 , k , s , 7 , 76 , , , 97 , 93 , 85 , 1 , 33 , , 64 , 46 , 5 , 35 , 66 , 88 , 32 , 6 , 9 , , 100 , 43 , 33 , 17 , n , 36 , l , 7 , 30 , 56 , 10 , 66 , 3 , 41 , 90 , 6 , w , 59 , 5 , 33 , 81 , n , 96 , 51 , m , k , 21 , 79 , 95 , 36 , 22 , 58 , 82 , p , 2 , 25 , s , 56 , 52 , 98 , 45 , 75 , 7 , 60 , 21 , 45 , 84 , 88 , 23 , 90 , 71 , 94 , 60 , 7 , 44 , 93 , 42 , 2 , 51 , 57 , 61 , , x , , z , 57 , 13 , 98 , g , 64 , 28 , 15 , 28 , 69 , d , 15 , 22 , 100 , 12 , , 69 , 89 , 28 , 20 , 22 , 69 , o , t , d , 37 , 44 , 94 , x , 98 , , x , 27 , 47 , x , 57 , 32 , , 26 , 26 , 41 , 34 , 100 , 93 , 76 , 67 , 30 , 9 , 40 , 55 , d , 8 , 71 , 99 , 61 , 5 , r , x , 69 , , 38 , 78 , , 24 , 86 , 44 , 80 , 93 , 5 , 11 , 28 , 25 , 1 , 86 , u , , 44 , 6 , , x , 100 , 89 , 68 , 99 , x , 72 , 18 , 61 , , 45 , 81 , 49 , m , 58 , 70 , 61 , , 0 , 83 , 74 , 28 , 5 , 87 , 42 , m , 21 , 37 , 38 , w , 92 , 8 , , 38 , 71 , 4 , 86 , g , o , 91 , 72 , 66 , 48 , n , 45 , 62 , 31 , 82 , 100 , 99 , 93 , 94 , 54 , m , 33 , w , 72 , 18 , 77 , 15 , q , 14 , b , 22 , 98 , j , , 2 , 2 , 51 , 86 , 46 , 18 , , 25 , 35 , 52 , 1 , , , 76 , 81 , 94 , , 65 , 35 , 42 , , 10 , 4 , a , , x , , a , z , 85 , i , 62 , 15 , 38 , m , r , 40 , 13 , j , 12 , 36 , 47 , 65 , 76 , c , 12 , 4 , 82 , 46 , q , 77 , 16 , 7 , 13 , 5 , 88 , 100 , 99 , 77 , q , q , 95 , 11 , 7 , 49 , d , 83 , 53 , 61 , i , 46 , 96 , 39 , 44 , , 31 , 52 , 0 , , h , 60 , 29 , c , 68 , k , 33 , 68 , 100 , 71 , 67 , 28 , 60 , 41 , 44 , 96 , 57 , a , g , k , 99 , , 32 , 92 , 42 , 90 , 7 , 52 , , 69 , 1 , 91 , , , , 67 , , 49 , 15 , 36 , 24 , 83 , x , q , q , 4 , 10 , s , 74 , 45 , t , 94 , 35 , 20 , 47 , 9 , m , 58 , v , z , 66 , 37 , 55 , e , 98 , , 77 , 88 , , 85 , 96 , 87 , s , , 21 , n , 71 , 47 , 51 , 69 , 89 , 79 , q , 16 , 47 , 88 , 22 , , , 90 , 58 , 54 , 40 , 99 , 2 , z , e , v , 73 , 88 , 72 , 12 , 23 , v , 13 , h , 30 , 39 , g , 34 , h , 33 , , 47 , t , 83 , 78 , k , x , 48 , b , 84 , k , , o , 80 , 44 , 11 , b , 20 , 65 , n , u , 58 , j , w , 8 , 18 , 66 , 72 , 78 , 2 , 15 , 79 , i , 7 , k , 71 , 61 , 92 , 57 , 76 , e , 95 , 57 , 58 , l , 90 , 98 , 9 , 73 , 90 , 1 , 38 , 75 , 65 , 30 , 74 , 22 , 22 , 33 , 1 , 2 , g , 50 , o , p , 67 , s , 18 , 73 , z , 0 , h , 43 , 92 , 88 , j';
+------------------+-----------------------------+-----+------+-----+----------+-----------+-----------+-----------+-----------+----------+--------+-------+ | benchmark | subject | set | revs | its | mem_peak | best | mean | mode | worst | stdev | rstdev | diff | +------------------+-----------------------------+-----+------+-----+----------+-----------+-----------+-----------+-----------+----------+--------+-------+ | TrimExplodeBench | bench_trimExplode_old | 0 | 1000 | 5 | 577,328b | 538.255μs | 566.207μs | 550.838μs | 618.631μs | 29.232μs | 5.16% | 1.03x | | TrimExplodeBench | bench_trimExplode_candidate | 0 | 1000 | 5 | 577,336b | 538.232μs | 547.454μs | 550.331μs | 551.910μs | 5.178μs | 0.95% | 1.00x | +------------------+-----------------------------+-----+------+-----+----------+-----------+-----------+-----------+-----------+----------+--------+-------+
New candidate seems to be a litte bit faster, but still "almost equal".
+------------------+-----------------------------------------------+-----+------+-----+----------+-------------+-------------+-------------+-------------+----------+--------+-------+ | benchmark | subject | set | revs | its | mem_peak | best | mean | mode | worst | stdev | rstdev | diff | +------------------+-----------------------------------------------+-----+------+-----+----------+-------------+-------------+-------------+-------------+----------+--------+-------+ | TrimExplodeBench | bench_trimExplode_old_removeEmptyValues | 0 | 1000 | 5 | 574,816b | 1,158.764μs | 1,181.165μs | 1,169.680μs | 1,218.746μs | 21.701μs | 1.84% | 1.00x | | TrimExplodeBench | bench_trimExplode_candidate_removeEmptyValues | 0 | 1000 | 5 | 577,360b | 1,607.001μs | 1,679.464μs | 1,660.833μs | 1,783.334μs | 57.386μs | 3.42% | 1.42x | +------------------+-----------------------------------------------+-----+------+-----+----------+-------------+-------------+-------------+-------------+----------+--------+-------+
New candidate seems to be slower.
String, shortened, like used in configuration or database CSV references¶
static $string = 'be_users_14,,,tx_whatever_19,28,4321,,pages_1';
+------------------+-----------------------------+-----+------+-----+----------+---------+---------+---------+---------+---------+--------+-------+ | benchmark | subject | set | revs | its | mem_peak | best | mean | mode | worst | stdev | rstdev | diff | +------------------+-----------------------------+-----+------+-----+----------+---------+---------+---------+---------+---------+--------+-------+ | TrimExplodeBench | bench_trimExplode_old | 0 | 1000 | 5 | 475,688b | 8.241μs | 8.431μs | 8.310μs | 8.644μs | 0.170μs | 2.02% | 1.12x | | TrimExplodeBench | bench_trimExplode_candidate | 0 | 1000 | 5 | 475,696b | 7.319μs | 7.511μs | 7.401μs | 7.753μs | 0.173μs | 2.31% | 1.00x | +------------------+-----------------------------+-----+------+-----+----------+---------+---------+---------+---------+---------+--------+-------+
New candidate seems to be a litte bit faster.
+------------------+-----------------------------------------------+-----+------+-----+----------+----------+----------+----------+----------+---------+--------+-------+ | benchmark | subject | set | revs | its | mem_peak | best | mean | mode | worst | stdev | rstdev | diff | +------------------+-----------------------------------------------+-----+------+-----+----------+----------+----------+----------+----------+---------+--------+-------+ | TrimExplodeBench | bench_trimExplode_old_removeEmptyValues | 0 | 1000 | 5 | 475,704b | 12.096μs | 13.335μs | 13.246μs | 14.708μs | 0.837μs | 6.28% | 1.00x | | TrimExplodeBench | bench_trimExplode_candidate_removeEmptyValues | 0 | 1000 | 5 | 475,720b | 19.652μs | 20.403μs | 20.147μs | 21.500μs | 0.626μs | 3.07% | 1.53x | +------------------+-----------------------------------------------+-----+------+-----+----------+----------+----------+----------+----------+---------+--------+-------+
New candidate seems to be slower.
Summary¶
TYPO3 is making use of 3rd parameter $removeEmptyValues
(enabled) which means that new candidate actually might slow down things.
Anyway, additional measurements and reports are welcome here.
Updated by Dieter Porth over 5 years ago
Summary¶
The method trimExplodeNewSix or variations of it seems not to be faster than the old trimExplode. You get in some cases different results.
I wouldn't change the method, because it is used in 555 places.
Suggestion¶
The description of trimExplode should be changed and $limit should be renamed to $reformCount, because it has not a ordinary limit-function (see tests).
* Explodes a string fully into an array-stack and trims all values for whitespace. * If $onlyNonEmptyValues is set, then all blank ('') values are removed. * If $reformCount is greater 0, it will implode all overflow array-element into the last array-element . * If $reformCount is lower 0, it will remove the last $reformCount of of the array-stack
I know, my english is horribly germanized.
remark¶
I should have done unittests before publishing.
',g,g, g, g,' will cause different results in trimExplode and trimExplodeNew for limit=5 and remove=true, because trimExplodeNewFour generates ["g","g","g","g,"] and trimExplode generates ["g","g","g","g"] (last comma is missing).
',g,g, g, g,' will cause different indexing in trimExplode and trimExplodeNew for limit=0 and remove=true.
',g,g, g, g,' will cause different results in trimExplode and trimExplodeNewFour for limit=5 and remove=true, because trimExplodeNewFour generates ["g","g","g","g,"].
',g,g, g, g,' will cause different results in trimExplode and trimExplodeNewSix for limit=5 and remove=true, because trimExplodeNewFour generates ["g","g","g","g,"].
public static function trimExplodeNewFour($delim, $string, $removeEmptyValues = false, $limit = 0) { if ($limit > 0) { $result = array_map('trim', explode($delim, $string, $limit) ); } else { $result = array_map('trim', explode($delim, $string) ); } if ($removeEmptyValues === true) { $temp = []; foreach ($result as $value) { if (trim($value) !== '') { $temp[] = $value; } } $result = $temp; } return $result; } public static function trimExplodeNewSix($delim, $string, $removeEmptyValues = false, $limit = 0) { if ($limit > 0) { $result = []; $check = explode($delim, $string, $limit); foreach ($check as $value) { $result[] = trim($value); } } else { $check = explode($delim, $string); $result = []; foreach ($check as $value) { $result[] = trim($value); } } if ($removeEmptyValues === true) { $temp = []; foreach ($result as $value) { if (trim($value) !== '') { $temp[] = $value; } } $result = $temp; } return $result; }
Use the following-Test to check identical results
namespace Porth\Checker\Benchmark; use PHPUnit\Framework\TestCase; class TrimExplodeTest extends TestCase { // Tests conatins no negative limits. public function dataProvidertrimExplodeByVariation() { $result = []; $item = []; $item['expects'] = 'test to value of referenz-function'; foreach (['remove empty' => true, 'allow empty' => false] as $removeMessage => $removeEmpty) { $item['params']['removeEmptyValues'] = $removeEmpty; foreach (['limit all' => 0, 'limit five' => 5, 'limit hundred' => 100] as $limitMessage => $limit) { $item['params']['limit'] = $limit; foreach ([-3, 0, 1, 2, 3, 7, 13, 100] as $addLimit) { $parts = $addLimit + $limit; if ($parts >= 0) { foreach (['emptyTwo' => ',', 'emptyInlet' => ',g,,g,', 'nothingempty' => '',] as $addTest) { $item['params']['testString'] = $addTest; $baseMessage = $removeMessage . ' with ' . $limitMessage . ' and ' . $parts . ' parts '; $item['params']['testString'] .= rtrim(str_repeat('g,', $parts), ',') .$addTest; $item['message'] = $baseMessage . ' and add NO space'; $result[] = $item; $item['params']['testString'] .= rtrim(str_repeat(' g,', $parts), ',') .$addTest; $item['message'] = $baseMessage . ' and add right to parameter the space'; $result[] = $item; $item['params']['testString'] .= rtrim(str_repeat('g ,', $parts), ',') .$addTest; $item['message'] = $baseMessage . ' and add left to parameter the space'; $result[] = $item; $item['params']['testString'] .= rtrim(str_repeat(' g ,', $parts), ',') .$addTest; $item['message'] = $baseMessage . ' and add on both sides of parameter the space'; $result[] = $item; } } } } } return $result; } /** * * @dataProvider dataProvidertrimExplodeByVariation * @test */ public function trimExplodeByVariation($expects, $params, $message) { if (!isset($expects) && empty($expects)) { $this->assertSame(true, false, 'empty-data at the end of the provider or emopty dataprovider'); } else { $delim = ','; $six = \Porth\Checker\Benchmark\TrimExplode::trimExplodeNewSix($delim, $params['testString'], $params['removeEmptyValues'], $params['limit'] ); $four = \Porth\Checker\Benchmark\TrimExplode::trimExplodeNewFour($delim, $params['testString'], $params['removeEmptyValues'], $params['limit'] ); $new = \Porth\Checker\Benchmark\TrimExplode::trimExplodeNew($delim, $params['testString'], $params['removeEmptyValues'], $params['limit'] ); $old = \Porth\Checker\Benchmark\TrimExplode::trimExplode($delim, $params['testString'], $params['removeEmptyValues'], $params['limit'] ); $this->assertSame( json_encode($old), json_encode($new), ('Org->new: ' . $message . "\n".$params['testString']."\n".$params['limit']." - ".$params['removeEmptyValues']."\n" . json_encode($old) . "\n" . json_encode($new)) ); $this->assertSame( json_encode($old), json_encode($four), ('Org->four: ' . $message . "\n".$params['testString']."\n".$params['limit']." - ".$params['removeEmptyValues']. "\n" . json_encode($old) . "\n" . json_encode($four)) ); $this->assertSame( json_encode($old), json_encode($six), ('Org->six: ' . $message . "\n".$params['testString']."\n".$params['limit']." - ".$params['removeEmptyValues']. "\n" . json_encode($old) . "\n" . json_encode($four)) ); } } }
post scriptuum¶
benchmarks-tests (obsolet)¶
It was interesting for me, that the for-loop in php is as fast as the internal functions. Perhaps it is interesting for someone else.
Test with XAMPP7.2 /Windows 10.
I have not tested it with php7.3.
Oliver Hader #5: String, 1000 alpha-numerics, all wrapped by spaces, random number of empty items
+------------------+-------------------------------+-----+------+------+----------+-------------+--------------+----------------+ | benchmark | subject | set | revs | iter | mem_peak | time_rev | comp_z_value | comp_deviation | +------------------+-------------------------------+-----+------+------+----------+-------------+--------------+----------------+ | TrimExplodeBench | benchOld | 0 | 1000 | 0 | 550,784b | 1,605.462μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNew | 0 | 1000 | 0 | 550,784b | 1,588.716μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewFour | 0 | 1000 | 0 | 550,784b | 1,571.796μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewSix | 0 | 1000 | 0 | 550,784b | 2,179.349μs | 0.00σ | 0.00% | +------------------+-------------------------------+-----+------+------+----------+-------------+--------------+----------------+ | TrimExplodeBench | benchOldRemoveEmpty | 0 | 1000 | 0 | 548,896b | 3,901.338μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewRemoveEmpty | 0 | 1000 | 0 | 550,792b | 3,768.027μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewFourRemoveEmpty | 0 | 1000 | 0 | 550,792b | 3,886.772μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewSixRemoveEmpty | 0 | 1000 | 0 | 579,512b | 6,827.562μs | 0.00σ | 0.00% | +------------------+-------------------------------+-----+------+------+----------+-------------+--------------+----------------+ | TrimExplodeBench | benchOldRemoveEmptyLim100 | 0 | 1000 | 0 | 559,640b | 2,645.360μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewRemoveEmptyLim100 | 0 | 1000 | 0 | 493,432b | 403.837μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewFourRemoveEmptyLim100 | 0 | 1000 | 0 | 493,432b | 402.702μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewSixRemoveEmptyLim100 | 0 | 1000 | 0 | 493,432b | 453.241μs | 0.00σ | 0.00% | +------------------+-------------------------------+-----+------+------+----------+-------------+--------------+----------------+ | TrimExplodeBench | benchOldRemoveEmptyLim5 | 0 | 1000 | 0 | 555,760b | 2,527.818μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewRemoveEmptyLim5 | 0 | 1000 | 0 | 493,424b | 36.379μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewFourRemoveEmptyLim5 | 0 | 1000 | 0 | 493,432b | 41.819μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewSixRemoveEmptyLim5 | 0 | 1000 | 0 | 493,432b | 32.987μs | 0.00σ | 0.00% | +------------------+-------------------------------+-----+------+------+----------+-------------+--------------+----------------+
Oliver Hader #5: String, shortened, like used in configuration or database CSV references
+------------------+-----------------------------+-----+------+------+----------+----------+--------------+----------------+ | benchmark | subject | set | revs | iter | mem_peak | time_rev | comp_z_value | comp_deviation | +------------------+-----------------------------+-----+------+------+----------+----------+--------------+----------------+ | TrimExplodeBench | benchOld | 0 | 1000 | 0 | 482,488b | 22.468μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNew | 0 | 1000 | 0 | 482,488b | 23.473μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewFour | 0 | 1000 | 0 | 482,488b | 22.244μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewSix | 0 | 1000 | 0 | 482,488b | 30.038μs | 0.00σ | 0.00% | +------------------+-----------------------------+-----+------+------+----------+----------+--------------+----------------+ | TrimExplodeBench | benchOldRemoveEmpty | 0 | 1000 | 0 | 482,496b | 36.954μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewRemoveEmpty | 0 | 1000 | 0 | 482,496b | 46.706μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewFourRemoveEmpty | 0 | 1000 | 0 | 482,496b | 41.657μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewSixRemoveEmpty | 0 | 1000 | 0 | 482,496b | 44.545μs | 0.00σ | 0.00% | +------------------+-----------------------------+-----+------+------+----------+----------+--------------+----------------+ | TrimExplodeBench | benchOldRemoveEmptyLim5 | 0 | 1000 | 0 | 482,496b | 38.587μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewRemoveEmptyLim5 | 0 | 1000 | 0 | 482,496b | 31.861μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewFourRemoveEmptyLim5 | 0 | 1000 | 0 | 482,504b | 35.335μs | 0.00σ | 0.00% | | TrimExplodeBench | benchNewSixRemoveEmptyLim5 | 0 | 1000 | 0 | 482,504b | 31.838μs | 0.00σ | 0.00% | +------------------+-----------------------------+-----+------+------+----------+----------+--------------+----------------+
Updated by Dieter Porth over 5 years ago
I remarked in #4 (my private typo3-account), that trimExplode
shows in some cases other results than trimExplodeNew, trimExplodeNewFour and trimExplodeNewSix
*
See compare-test with phpunit in #4.
TYPO3 contains 555 places, where the function trimExplode is used.
I would close this ticket, because my suggested solution is not really better than the current version.
Updated by Susanne Moog over 5 years ago
- Status changed from Needs Feedback to Closed
Closed as requested by the author.