Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save salmanarshad2000/99ce15b5be1bd12d7523939397eec20c to your computer and use it in GitHub Desktop.
Save salmanarshad2000/99ce15b5be1bd12d7523939397eec20c to your computer and use it in GitHub Desktop.
PHP StartsWith and EndsWith Function Benchmarks
<?php
/**
* PHP StartsWith and EndsWith Function Benchmarks
*
* Function implementations taken from:
* https://stackoverflow.com/q/834303/87015
*
* Command line:
* php.exe -d memory_limit=128M startswith-endswith-benchmark.php
*/
php_sapi_name() === 'cli' or die;
define('NUMBER_OF_TESTS', 10000);
define('HAYSTACK_LENGTH', 8192);
function generateTests($count, $maxlen) {
$tests = array();
for ($i = 0; $i < $count; $i++) {
$haystackLength = rand(1, $maxlen);
$haystack = openssl_random_pseudo_bytes($haystackLength);
$needleLength = rand(1, $haystackLength);
$substr_s = substr($haystack, 0, $needleLength);
$substr_e = substr($haystack, -$needleLength);
$resultType = rand(0, 2);
if ($resultType === 0) {
$needle_s = $substr_s;
$needle_e = $substr_e;
}
if ($resultType === 1) {
while (($needle_s = openssl_random_pseudo_bytes($needleLength)) === $substr_s);
while (($needle_e = openssl_random_pseudo_bytes($needleLength)) === $substr_e);
}
if ($resultType === 2) {
$tokeep = rand(0, $needleLength - 1);
while (($needle_s = substr($substr_s, 0, $tokeep) . openssl_random_pseudo_bytes($needleLength - $tokeep)) === $substr_s);
while (($needle_e = substr($substr_e, 0, $tokeep) . openssl_random_pseudo_bytes($needleLength - $tokeep)) === $substr_e);
}
$tests[] = array('haystack' => $haystack, 'needle_s' => $needle_s, 'needle_e' => $needle_e, 'result' => $resultType === 0);
}
return $tests;
}
function startsWith_strpos($haystack, $needle) {
return $needle === '' || strrpos($haystack, $needle, -strlen($haystack)) !== false;
}
function endsWith_strpos($haystack, $needle) {
return ($needle === '') || (($spos = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $spos) !== false);
}
function startsWith_substr($haystack, $needle) {
return substr($haystack, 0, strlen($needle)) === $needle;
}
function endsWith_substr($haystack, $needle) {
return $needle === '' || substr($haystack, -strlen($needle)) === $needle;
}
function startsWith_substrcompare($haystack, $needle) {
return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}
function endsWith_substrcompare($haystack, $needle) {
return substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
$functions = array();
$functions['s']['startsWith_strpos'] = 0.0;
$functions['e']['endsWith_strpos'] = 0.0;
$functions['s']['startsWith_substr'] = 0.0;
$functions['e']['endsWith_substr'] = 0.0;
$functions['s']['startsWith_substrcompare'] = 0.0;
$functions['e']['endsWith_substrcompare'] = 0.0;
echo 'Using PHP ' . PHP_VERSION . '...' . PHP_EOL;
echo 'Generating tests...' . PHP_EOL;
$tests = generateTests(NUMBER_OF_TESTS, HAYSTACK_LENGTH);
echo 'Checking functions...' . PHP_EOL;
foreach ($functions['s'] as $function => $time) {
foreach ($tests as $test) {
$result = $function($test['haystack'], $test['needle_s']);
if ($result !== $test['result']) {
die('Function ' . $function . ' failed tests');
}
}
}
foreach ($functions['e'] as $function => $time) {
foreach ($tests as $test) {
$result = $function($test['haystack'], $test['needle_e']);
if ($result !== $test['result']) {
die('Function ' . $function . ' failed tests');
}
}
}
echo 'Running benchmark, press CTRL+C to stop...' . PHP_EOL;
for ($i = 1; true; $i++) {
foreach ($functions['s'] as $function => &$time) {
$t1 = microtime(true);
foreach ($tests as $test) {
$result = $function($test['haystack'], $test['needle_s']);
}
$t2 = microtime(true);
$time += $t2 - $t1;
}
unset($time);
foreach ($functions['e'] as $function => &$time) {
$t1 = microtime(true);
foreach ($tests as $test) {
$result = $function($test['haystack'], $test['needle_e']);
}
$t2 = microtime(true);
$time += $t2 - $t1;
}
unset($time);
if ($i % 10 === 0) {
foreach ($functions as $temp) {
foreach ($temp as $function => $time) {
echo sprintf('%-32s %8s ms avg. per %d executions', $function, number_format($time * 1000 / $i, 2), count($tests)) . PHP_EOL;
}
}
echo PHP_EOL;
}
}
@PerfilovStanislav
Copy link

return $haystack[-1] === $needle[-1]
    ? \substr_compare($haystack, $needle, -\strlen($needle)) === 0
    : false;

is faster

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