Skip to content

Instantly share code, notes, and snippets.

@andrewdalpino
Last active August 13, 2023 10:39
Show Gist options
  • Save andrewdalpino/492bbf4261d31dad5f847f9f4c42cbf9 to your computer and use it in GitHub Desktop.
Save andrewdalpino/492bbf4261d31dad5f847f9f4c42cbf9 to your computer and use it in GitHub Desktop.
This is a performance benchmark comparing PHP SplStack, SplQueue, and plain array performance for insert and read/remove operations.
<?php
namespace PhpBenchmarks;
use SplStack;
use SplQueue;
const NUM_TEST_ITEMS = 100000;
const DATA_SIZE = 32; //Bytes.
$data = [];
$stack = new SplStack();
$queue = new SplQueue();
$array = [];
foreach (range(1, NUM_TEST_ITEMS) as $i) {
$data[$i] = random_bytes(DATA_SIZE);
}
echo 'Testing SplStack (Push) ... ';
$start = microtime(true);
foreach (range(1, NUM_TEST_ITEMS) as $i) {
$stack->push($data[$i]);
}
$stop = microtime(true);
echo number_format(NUM_TEST_ITEMS) . ' items in ' . (string) ($stop - $start) . ' seconds.' . "\n";
echo 'Testing Array (Push) ... ';
$start = microtime(true);
foreach (range(1, NUM_TEST_ITEMS) as $i) {
$array[] = $data[$i];
}
$stop = microtime(true);
echo number_format(NUM_TEST_ITEMS) . ' items in ' . (string) ($stop - $start) . ' seconds.' . "\n";
echo "\n";
echo 'Testing SplStack (Pop) ... ';
$start = microtime(true);
foreach (range(1, NUM_TEST_ITEMS) as $i) {
$stack->pop();
}
$stop = microtime(true);
echo number_format(NUM_TEST_ITEMS) . ' items in ' . (string) ($stop - $start) . ' seconds.' . "\n";
echo 'Testing Array (Pop) ... ';
$start = microtime(true);
foreach (range(1, NUM_TEST_ITEMS) as $i) {
array_pop($array);
}
$stop = microtime(true);
echo number_format(NUM_TEST_ITEMS) . ' items in ' . (string) ($stop - $start) . ' seconds.' . "\n";
echo "\n";
echo 'Testing SplQueue (Push) ... ';
$start = microtime(true);
foreach (range(1, NUM_TEST_ITEMS) as $i) {
$queue->push($data[$i]);
}
$stop = microtime(true);
echo number_format(NUM_TEST_ITEMS) . ' items in ' . (string) ($stop - $start) . ' seconds.' . "\n";
echo 'Testing Array (Push) ... ';
$start = microtime(true);
foreach (range(1, NUM_TEST_ITEMS) as $i) {
$array[] = $data[$i];
}
$stop = microtime(true);
echo number_format(NUM_TEST_ITEMS) . ' items in ' . (string) ($stop - $start) . ' seconds.' . "\n";
echo "\n";
echo 'Testing SplQueue (Shift) ... ';
$start = microtime(true);
foreach (range(1, NUM_TEST_ITEMS) as $i) {
$queue->shift();
}
$stop = microtime(true);
echo number_format(NUM_TEST_ITEMS) . ' items in ' . (string) ($stop - $start) . ' seconds.' . "\n";
echo 'Testing Array (Shift) ... ';
$start = microtime(true);
foreach (range(1, NUM_TEST_ITEMS) as $i) {
array_shift($array);
}
$stop = microtime(true);
echo number_format(NUM_TEST_ITEMS) . ' items in ' . (string) ($stop - $start) . ' seconds.' . "\n";
echo "\n";
@andrewdalpino
Copy link
Author

Results:

Testing SplStack (Push) ... 100,000 items in 0.012847900390625 seconds.
Testing Array (Push) ... 100,000 items in 0.0077648162841797 seconds.

Testing SplStack (Pop) ... 100,000 items in 0.0076310634613037 seconds.
Testing Array (Pop) ... 100,000 items in 0.0084760189056396 seconds.

Testing SplQueue (Push) ... 100,000 items in 0.011080026626587 seconds.
Testing Array (Push) ... 100,000 items in 0.0070550441741943 seconds.

Testing SplQueue (Shift) ... 100,000 items in 0.007843017578125 seconds.
Testing Array (Shift) ... 100,000 items in 14.495656967163 seconds.

Curiously, plain arrays perform better while inserting, but worse when read/removing versus the SplStack. As suspected, plain array shift (an O(N) operation because it has to reindex the array) is by far slower than the SplQueue shift (an O(1) operation since the implementation is a pointer machine and only involves reassigning pointers).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment