Monday, 13 August 2018

PHP: how to get the last element of an array

What is the best way, in terms of performance and elegance, to get the last element of an array in PHP?
I tried in 5 different ways and the results are very interesting. For the timings, I considered an array of 1.000.000 elements and every operation was repeated 1000 times. Take the timings with a bit of salt!
  • end($array); reset($array); In my opinion is the most elegant way, and also one of the fastest. It takes only 0.73 ms. The end function is very fast because it works on array’s internal pointer. That’s why we need to use reset to set the internal pointer back to the first element of the array, so we can continue to work on our data structure without worries.
  • array_slice($array, -1)[0]; It’s the most creative solution, but unfortunately it’s also one of the slowest: it takes 13.56 s. Probably due to the creation of a new array with every call.
  • end(array_values($array)); It’ s the worst solution, both in terms of elegance and performance: it takes 176.85 s! Fast using end to work on array internal pointer, but terribly slow creating a new array every time with array_values, used only to avoid the reset call.
  • $array[count($array) — 1]; One of the fastest and concise solution, but not very elegant according to my personal taste, it takes 5.2 ms.
  • array_pop($array); The fastest solution, it takes only 0.45 ms. Unfortunately it has a major drawback: it shortens the array by one element while returning it, so it is disruptive on your data structure. If it’s not a problem, this is probably the best solution for you.
<?php

$loopLimit = 1000;
$array = range(0, 1000000);

$value = null;
$startTime = microtime(true);
for ($i = 0; $i < $loopLimit; $i ++) {
    $value = end($array);
    reset($array);
}
$endTime = microtime(true);

$elapsedTime = $endTime - $startTime;
echo "end - reset: $elapsedTime\n";

$startTime = microtime(true);
for ($i = 0; $i < $loopLimit; $i ++) {
    $value = array_slice($array, -1)[0];
}
$endTime = microtime(true);

$elapsedTime = $endTime - $startTime;
echo "array_slice: $elapsedTime\n";

$startTime = microtime(true);
for ($i = 0; $i < $loopLimit; $i ++) {
    $value = end(array_values($array));
}
$endTime = microtime(true);

$elapsedTime = $endTime - $startTime;
echo "end - array_values: $elapsedTime\n";

$startTime = microtime(true);
for ($i = 0; $i < $loopLimit; $i ++) {
    $value = $array[count($array) - 1];
}
$endTime = microtime(true);

$elapsedTime = $endTime - $startTime;
echo "count: $elapsedTime\n";

$startTime = microtime(true);
for ($i = 0; $i < $loopLimit; $i ++) {
    $value = array_pop($array);
}
$endTime = microtime(true);

$elapsedTime = $endTime - $startTime;
echo "array_pop: $elapsedTime\n";

0 comments:

Post a Comment