这个帖子中的许多答案为我们提供了许多不同的 Select .为了能够从中 Select ,我需要了解他们的行为和表现.在这个回答中,我将与您分享我的发现,并以PHP版本5.6.38
、7.2.10
和7.3.0RC1
(expected Dec 13 2018)为基准.
我将测试的选项(<<option code>>
)包括:
(提到的功能:array_key_last、array_keys、array_pop、array_slice、array_values、count、end、reset)
要结合的测试输入(<<input code>>
秒):
- null=
$array = null;
- empty =
$array = [];
- last_null=
$array = ["a","b","c",null];
- auto_idx =
$array = ["a","b","c","d"];
- shuffle=
$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
- 100=
$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
- 100000 =
$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }
对于测试,我将使用5.6.38
、7.2.10
和7.3.0RC1
PHP docker containers,如:
sudo docker run -it --rm php:5.6.38-cli-stretch php -r '<<<CODE HERE>>>'
以上列出的<<option code>>
和<<input code>>
的每个组合都将在所有版本的PHP上运行.对于每个测试运行,使用以下代码段:
<<input code>> error_reporting(E_ALL); <<option code>> error_reporting(0); $before=microtime(TRUE); for($i=0;$i<100;$i++){echo ".";for($j=0;$j<100;$j++){ <<option code>> }}; $after=microtime(TRUE); echo "\n"; var_dump($x); echo round(($after-$before)/(100*100)*1000*1000*1000);
对于每次运行,这将var_dump最后检索到的测试输入的最后一个值,并打印一次迭代的平均持续时间in femtoseconds(0.000000000000001秒).
结果如下:
/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
|| || T E S T I N P U T - 5 . 6 . 3 8 || T E S T I N P U T - 7 . 2 . 1 0 || T E S T I N P U T - 7 . 3 . 0 R C 1 ||
|| || null | empty | last_null | auto_idx | shuffle | 100 | 100000 || null | empty | last_null | auto_idx | shuffle | 100 | 100000 || null | empty | last_null | auto_idx | shuffle | 100 | 100000 ||
||============================OPTIONS - ERRORS==========================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
|| 1. $x = array_values(array_slice($array, -1))[0]; || W1 + W2 | N1 | - | - | - | - | - || W1 + W2 | N1 | - | - | - | - | - || W1 + W2 | N1 | - | - | - | - | - ||
|| 2. $x = array_slice($array, -1)[0]; || W1 | N1 | - | - | - | - | - || W1 | N1 | - | - | - | - | - || W1 | N1 | - | - | - | - | - ||
|| 3. $x = array_pop((array_slice($array, -1))); || W1 + W3 | - | - | - | - | - | - || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 ||
|| 4. $x = array_pop((array_slice($array, -1, 1))); || W1 + W3 | - | - | - | - | - | - || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 ||
|| 5. $x = end($array); reset($array); || W4 + W5 | - | - | - | - | - | - || W4 + W5 | N2 | N2 | N2 | N2 | N2 | N2 || W4 + W5 | - | - | - | - | - | - ||
|| 6. $x = end((array_values($array))); || W2 + W4 | - | - | - | - | - | - || W2 + N2 + W4 | - | - | - | - | - | - || W2 + N2 + W4 | N2 | N2 | N2 | N2 | N2 | N2 ||
|| 7. $x = $array[count($array)-1]; || - | N3 | - | - | - | - | - || W7 | N3 | - | - | - | - | - || W7 | N3 | - | - | - | - | - ||
|| 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || W6 | N3 + N4 | - | - | - | - | - || W6 + W7 | N3 + N4 | - | - | - | - | - || W6 + W7 | N3 + N4 | - | - | - | - | - ||
|| 9. $x = $array[] = array_pop($array); || W3 | - | - | - | - | - | - || W3 | - | - | - | - | - | - || W3 | - | - | - | - | - | - ||
|| 10. $x = $array[array_key_last($array)]; || F1 | F1 | F1 | F1 | F1 | F1 | F1 || F2 | F2 | F2 | F2 | F2 | F2 | F2 || W8 | N4 | F2 | F2 | F2 | F2 | F2 ||
||========================OPTIONS - VALUE RETRIEVED=====================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
|| 1. $x = array_values(array_slice($array, -1))[0]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 2. $x = array_slice($array, -1)[0]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 3. $x = array_pop((array_slice($array, -1))); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 4. $x = array_pop((array_slice($array, -1, 1))); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 5. $x = end($array); reset($array); || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 6. $x = end((array_values($array))); || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 7. $x = $array[count($array)-1]; || NULL | NULL | NULL | string(1) "d" | string(1) "b" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "b" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "b" | int(99) | int(99999) ||
|| 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 9. $x = $array[] = array_pop($array); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 10. $x = $array[array_key_last($array)]; || N/A | N/A | N/A | N/A | N/A | N/A | N/A || N/A | N/A | N/A | N/A | N/A | N/A | N/A || N/A | N/A | N/A | N/A | N/A | N/A | N/A ||
||=================OPTIONS - FEMTOSECONDS PER ITERATION=================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
|| 1. $x = array_values(array_slice($array, -1))[0]; || 803 | 466 | 390 | 384 | 373 | 764 | 1.046.642 || 691 | 252 | 101 | 128 | 93 | 170 | 89.028 || 695 | 235 | 90 | 97 | 95 | 188 | 87.991 ||
|| 2. $x = array_slice($array, -1)[0]; || 414 | 349 | 252 | 248 | 246 | 604 | 1.038.074 || 373 | 249 | 85 | 91 | 90 | 164 | 90.750 || 367 | 224 | 78 | 85 | 80 | 155 | 86.141 ||
|| 3. $x = array_pop((array_slice($array, -1))); || 724 | 228 | 323 | 318 | 350 | 673 | 1.042.263 || 988 | 285 | 309 | 317 | 331 | 401 | 88.363 || 877 | 266 | 298 | 300 | 326 | 403 | 87.279 ||
|| 4. $x = array_pop((array_slice($array, -1, 1))); || 734 | 266 | 358 | 356 | 349 | 699 | 1.050.101 || 887 | 288 | 316 | 322 | 314 | 408 | 88.402 || 935 | 268 | 335 | 315 | 313 | 403 | 86.445 ||
|| 5. $x = end($array); reset($array); || 715 | 186 | 185 | 180 | 176 | 185 | 172 || 674 | 73 | 69 | 70 | 66 | 65 | 70 || 693 | 65 | 85 | 74 | 68 | 70 | 69 ||
|| 6. $x = end((array_values($array))); || 877 | 205 | 320 | 337 | 304 | 2.901 | 7.921.860 || 948 | 300 | 336 | 308 | 309 | 509 | 29.696.951 || 946 | 262 | 301 | 309 | 302 | 499 | 29.234.928 ||
|| 7. $x = $array[count($array)-1]; || 123 | 300 | 137 | 139 | 143 | 140 | 144 || 312 | 218 | 48 | 53 | 45 | 47 | 51 || 296 | 217 | 46 | 44 | 53 | 53 | 55 ||
|| 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || 494 | 593 | 418 | 435 | 399 | 3.873 | 12.199.450 || 665 | 407 | 103 | 109 | 114 | 431 | 30.053.730 || 647 | 445 | 91 | 95 | 96 | 419 | 30.718.586 ||
|| 9. $x = $array[] = array_pop($array); || 186 | 178 | 175 | 188 | 180 | 181 | 186 || 83 | 78 | 75 | 71 | 74 | 69 | 83 || 71 | 64 | 70 | 64 | 68 | 69 | 81 ||
|| 10. $x = $array[array_key_last($array)]; || N/A | N/A | N/A | N/A | N/A | N/A | N/A || N/A | N/A | N/A | N/A | N/A | N/A | N/A || 370 | 223 | 49 | 52 | 61 | 57 | 52 ||
\=========================================================================================================================================================================================================================================================================================================================================================================================================================/
上述Fatal、Warning和Notice代码翻译为:
F1 = Fatal error: Call to undefined function array_key_last() in Command line code on line 1
F2 = Fatal error: Uncaught Error: Call to undefined function array_key_last() in Command line code:1
W1 = Warning: array_slice() expects parameter 1 to be array, null given in Command line code on line 1
W2 = Warning: array_values() expects parameter 1 to be array, null given in Command line code on line 1
W3 = Warning: array_pop() expects parameter 1 to be array, null given in Command line code on line 1
W4 = Warning: end() expects parameter 1 to be array, null given in Command line code on line 1
W5 = Warning: reset() expects parameter 1 to be array, null given in Command line code on line 1
W6 = Warning: array_keys() expects parameter 1 to be array, null given in Command line code on line 1
W7 = Warning: count(): Parameter must be an array or an object that implements Countable in Command line code on line 1
W8 = Warning: array_key_last() expects parameter 1 to be array, null given in Command line code on line 1
N1 = Notice: Undefined offset: 0 in Command line code on line 1
N2 = Notice: Only variables should be passed by reference in Command line code on line 1
N3 = Notice: Undefined offset: -1 in Command line code on line 1
N4 = Notice: Undefined index: in Command line code on line 1
根据这一结果,我得出以下结论:
- newer versions of PHP perform better with the exception of these options that became significantly slower:
- option .6.
$x = end((array_values($array)));
- option .8.
$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
- these options scale best for very large arrays:
- option .5.
$x = end($array); reset($array);
- option .7.
$x = $array[count($array)-1];
- option .9.
$x = $array[] = array_pop($array);
- option 10.
$x = $array[array_key_last($array)];
(自PHP7.3起)
- these options should only be used for auto-indexed arrays:
- option .7.
$x = $array[count($array)-1];
(由于使用count
)
- option .9.
$x = $array[] = array_pop($array);
(由于赋值丢失原始密钥)
- this option does not preserve the array's internal pointer
- option .5.
$x = end($array); reset($array);
- this option is an attempt to modify option .5. to preserve the array's internal pointer (but sadly it does not scale well for very large arrays)
- option .6.
$x = end((array_values($array)));
- the new
array_key_last
function seems to have none of the above mentioned limitations with the exception of still being an RC at the time of this writing (so use the RC or await it's release Dec 2018):
- option 10.
$x = $array[array_key_last($array)];
(自PHP7.3起)
这取决于你是否能在选项9上做出改变.