nette/http — pull request #33 by JanTvrdik (2014-12-18 17:01:57+00:00)
Title: RequestFactory: optimized UTF-8 validation performance

Benchmark:

~~~php
$s = str_repeat('a', 1e6) . 'b';
$datasets = [
'valid' => [$s, TRUE],
'control character' => [str_replace('b', "\x00", $s), FALSE],
'invalid UTF-8' => [str_replace('b', "\xC0", $s), FALSE],
];

$tests = [
'NONCHARS' => function ($testCount, $s, $expected) {
for ($i = 0; $i < $testCount; $i++) {
$actual = !preg_match('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u', $s) && !preg_last_error();
}
assert($actual === $expected);
},
'CHARS' => function ($testCount, $s, $expected) {
for ($i = 0; $i < $testCount; $i++) {
$actual = preg_match('#^[\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]*\z#u', $s) && !preg_last_error();
}
assert($actual === $expected);
}
];

$testCount = 10;
$padLength = max(array_map('strlen', array_keys($datasets))) + 3;
foreach ($tests as $testName => $testCallback) {
printf("Test %s:\n", $testName);
foreach ($datasets as $datasetName => $dataset) {
$time = -microtime(TRUE);
$testCallback($testCount, ...$dataset);
$time += microtime(TRUE);
printf(" %s%5.0f ms\n", str_pad($datasetName, $padLength), $time * 1e3);
}
printf("\n");
}
~~~

Results:
~~~
Test NONCHARS:
valid 252 ms
control character 248 ms
invalid UTF-8 6 ms

Test CHARS:
valid 54 ms
control character 147 ms
invalid UTF-8 7 ms
~~~