Skip to content

Instantly share code, notes, and snippets.

@sun
Last active August 29, 2015 14:04
Show Gist options
  • Save sun/287c1f75528dc75cdb96 to your computer and use it in GitHub Desktop.
Save sun/287c1f75528dc75cdb96 to your computer and use it in GitHub Desktop.
Bench various ways of natively looping over PHP arrays
<?php
# Simple PHP 5.4+ bench script for CLI.
const ITERATIONS = 1000;
const ARRAY_SIZE = 1000;
define('CONDITION', 'item' . (ARRAY_SIZE - 1));
error_reporting(E_ALL | E_STRICT);
setlocale(LC_ALL, 'C');
register_shutdown_function(function () {
echo PHP_EOL;
$memory_peak_end = memory_get_peak_usage();
echo 'Peak memory after test: ', format_kb($memory_peak_end), PHP_EOL;
echo 'Memory difference: ', format_kb($memory_peak_end, MEMORY_PEAK_START), PHP_EOL;
});
function format_kb($size, $diff_base_size = NULL) {
$out = '';
if (isset($diff_base_size)) {
$out = ($size = $size - $diff_base_size) > 0 ? '+' : '';
}
$out .= number_format($size / 1024) . ' KB';
return $out;
}
function no_op($text) {
return $text;
}
/**
* Initialization.
*/
define('MEMORY_PEAK_START', memory_get_peak_usage());
echo 'Peak memory before test: ', format_kb(MEMORY_PEAK_START), PHP_EOL;
echo 'Iterations: ', ITERATIONS, PHP_EOL;
echo 'Array size: ', ARRAY_SIZE, PHP_EOL, PHP_EOL;
function create_giant_array() {
$array = array();
for ($i = 0; $i <= ARRAY_SIZE; $i++) {
$array[] = 'item' . $i;
}
return $array;
}
function create_giant_linkedlist() {
$array = new SplDoublyLinkedList();
for ($i = 0; $i <= ARRAY_SIZE; $i++) {
$array[] = 'item' . $i;
}
return $array;
}
/**
* Test cases.
*/
$tests['nothing'] = function () {
};
$tests['no_op'] = function () {
$text = no_op('some string');
};
$tests['foreach'] = function () {
$array = create_giant_array();
foreach ($array as $key => $value) {
if ($value === CONDITION) {
$return = $value;
}
}
return $return;
};
$tests['for'] = function () {
$array = create_giant_array();
for ($i = 0; $i < count($array); $i++) {
if ($array[$i] === CONDITION) {
$return = $array[$i];
}
}
return $return;
};
$tests['for $ii'] = function () {
$array = create_giant_array();
for ($i = 0, $ii = count($array); $i < $ii; $i++) {
if ($array[$i] === CONDITION) {
$return = $array[$i];
}
}
return $return;
};
$tests['SplDoublyLinkedList'] = function () {
$array = create_giant_linkedlist();
foreach ($array as $key => $value) {
if ($value === CONDITION) {
$return = $value;
}
}
return $return;
};
$tests['while'] = function () {
$array = create_giant_array();
while (FALSE !== $value = current($array)) {
$key = key($array);
if ($value === CONDITION) {
$return = $value;
}
next($array);
}
return $return;
};
#### REVERSE TESTS
$tests['Reverse: foreach'] = function () {
$array = array_reverse(create_giant_array(), true);
foreach ($array as $key => $value) {
if ($value === CONDITION) {
$return = $value;
}
}
return $return;
};
$tests['Reverse: for'] = function () {
$array = create_giant_array();
for ($i = count($array) - 1; $i >= 0; $i--) {
if ($array[$i] === CONDITION) {
$return = $array[$i];
}
}
return $return;
};
$tests['Reverse: for $ii'] = function () {
return "n/a (same as: Reverse: for)";
};
$tests['Reverse: SplDoublyLinkedList'] = function () {
$array = create_giant_linkedlist();
$array->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
foreach ($array as $key => $value) {
if ($value === CONDITION) {
$return = $value;
}
}
return $return;
};
$tests['Reverse: while'] = function () {
$array = create_giant_array();
end($array);
while (FALSE !== $value = current($array)) {
$key = key($array);
if ($value === CONDITION) {
$return = $value;
}
prev($array);
}
return $return;
};
/**
* Test runner.
*/
$results = array();
foreach ($tests as $name => $test) {
$start = microtime(true);
for ($i = 0; $i < ITERATIONS; ++$i) {
$results[$name] = $test();
}
$stop = microtime(true);
printf("%-30.30s %2.3f seconds -- %s\n", $name . ':', $stop - $start, var_export($results[$name], TRUE));
}
$ php bench.loop.php
Peak memory before test: 162 KB
Iterations: 1000
Array size: 1000
nothing: 0.013 seconds -- NULL
no_op: 0.015 seconds -- NULL
foreach: 0.928 seconds -- 'item999'
for: 4.970 seconds -- 'item999'
for $ii: 0.986 seconds -- 'item999'
SplDoublyLinkedList: 1.351 seconds -- 'item999'
while: 12.709 seconds -- 'item999'
Reverse: foreach: 1.006 seconds -- 'item999'
Reverse: for: 0.985 seconds -- 'item999'
Reverse: for $ii: 0.011 seconds -- 'n/a (same as: Reverse: for)'
Reverse: SplDoublyLinkedList: 1.384 seconds -- 'item999'
Reverse: while: 12.782 seconds -- 'item999'
Peak memory after test: 339 KB
Memory difference: +177 KB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment