Skip to content

stripos with large haystack has bad performance #7847

Description

@Jumping-Beaver

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:

haystack_dup = zend_string_tolower(haystack);

Test case:

<?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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions