[php-src] Issue #7847: stripos has very bad performance
| From: | woho | Date: | Tue, 28 Dec 2021 18:55:06 +0000 |
| Subject: | [php-src] Issue #7847: stripos has very bad performance | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-238614@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/7847
Author: woho
### Description
stripos is slow because both input strings are always lowercased completely. This also entails
unnecessary memory consumption.
preg_match with case-insensitive flag is a much faster alternative.
Source code: https://github.com/php/php-src/blob/9362d6f5f08bf5f86fc30cf12433e1634f746c4d/ext/standard/string.c#L1914
Test case:
```php
<?php
$haystack = str_repeat('A', 1e+7) . 'BBB';
$repetitions = 0;
$start = microtime(true);
do {
strpos($haystack, 'bbb');
$repetitions += 1;
} while (microtime(true) - $start < 5);
$rate = round($repetitions / (microtime(true) - $start));
$rate = str_pad($rate, 8, ' ', STR_PAD_LEFT);
print("strpos: $rate / second\n");
$repetitions = 0;
$start = microtime(true);
do {
stripos($haystack, 'bbb');
$repetitions += 1;
} while (microtime(true) - $start < 5);
$rate = round($repetitions / (microtime(true) - $start));
$rate = str_pad($rate, 8, ' ', STR_PAD_LEFT);
print("stripos: $rate / second\n");
$repetitions = 0;
$start = microtime(true);
do {
preg_match('/bbb/i', $haystack, $match, PREG_OFFSET_CAPTURE);
$repetitions += 1;
} while (microtime(true) - $start < 5);
$rate = round($repetitions / (microtime(true) - $start));
$rate = str_pad($rate, 8, ' ', STR_PAD_LEFT);
print("preg_match: $rate / second\n");
```
Example output:
```
strpos: 1192 / second
stripos: 176 / second
preg_match: 1118 / second
```
### PHP Version
PHP 8.0.14
### Operating System
_No response_