Skip to content

Instantly share code, notes, and snippets.

@realityking
Last active December 17, 2015 23:39
Show Gist options
  • Save realityking/5690703 to your computer and use it in GitHub Desktop.
Save realityking/5690703 to your computer and use it in GitHub Desktop.
<?php
$utf8_s = 'Iñtërnâtiônàlizætiøn';
$ascii_s = 'Internationalisation';
$utf8_m = 'Geocaching, auch GPS-Schnitzeljagd genannt, ist eine Art elektronische Schatzsuche oder Schnitzeljagd. Die Verstecke („Geocaches“, kurz „Caches“) werden anhand geografischer Koordinaten im World Wide Web veröffentlicht und können anschließend mit Hilfe eines GPS-Empfängers gesucht werden. Mit genauen Landkarten ist auch die Suche ohne GPS-Empfänger möglich. Ein Geocache ist in der Regel ein wasserdichter Behälter, in dem sich ein Logbuch sowie verschiedene kleine Tauschgegenstände befinden. Jeder Besucher trägt sich in das Logbuch ein, um seine erfolgreiche Suche zu dokumentieren. Anschließend wird der Geocache wieder an der Stelle versteckt, an der er zuvor gefunden wurde. Der Fund wird im Internet auf der zugehörigen Seite vermerkt und gegebenenfalls durch Fotos ergänzt. So können auch andere Personen – insbesondere der Verstecker oder „Owner“ – die Geschehnisse rund um den Geocache verfolgen. Weltweit existieren über 2 Millionen Geocaches.';
$ascii_m = 'Geocaching, auch GPS-Schnitzeljagd genannt, ist eine Art elektronische Schatzsuche oder Schnitzeljagd. Die Verstecke ("Geocaches", kurz "Caches") werden anhand geografischer Koordinaten im World Wide Web veroeffentlicht und koennen anschliessend mit Hilfe eines GPS-Empfaengers gesucht werden. Mit genauen Landkarten ist auch die Suche ohne GPS-Empfaenger moeglich. Ein Geocache ist in der Regel ein wasserdichter Behaelter, in dem sich ein Logbuch sowie verschiedene kleine Tauschgegenstaende befinden. Jeder Besucher traegt sich in das Logbuch ein, um seine erfolgreiche Suche zu dokumentieren. Anschliessend wird der Geocache wieder an der Stelle versteckt, an der er zuvor gefunden wurde. Der Fund wird im Internet auf der zugehoerigen Seite vermerkt und gegebenenfalls durch Fotos ergaenzt. So koennen auch andere Personen - insbesondere der Verstecker oder "Owner" - die Geschehnisse rund um den Geocache verfolgen. Weltweit existieren ueber 2 Millionen Geocaches.';
$utf8_l = file_get_contents(__DIR__ . '/utf8.txt');
$ascii_l = file_get_contents(__DIR__ . '/ascii.txt');
function f($i) {
return number_format($i, 4);
}
function string_is_ascii_u($str) {
// Search for any bytes which are outside the ASCII range...
return (\preg_match('/(?:[^\x00-\x7F])/', $str) !== 1);
}
function string_is_ascii_phputf8($string, $c)
{
$i = 0;
$t = microtime(true);
while($i < $c) {
$value = string_is_ascii_u($string);
++$i;
}
$tmp = microtime(true) - $t;
return $tmp;
}
function string_is_ascii_php($string, $c)
{
$i = 0;
$t = microtime(true);
while($i < $c) {
$value = string_is_ascii($string);
++$i;
}
$tmp = microtime(true) - $t;
return $tmp;
}
function string_is_ascii_mb($string, $c)
{
$i = 0;
$t = microtime(true);
while($i < $c) {
$value = mb_detect_encoding($string, 'ASCII', true);
++$i;
}
$tmp = microtime(true) - $t;
return $tmp;
}
$calls = 1000;
echo "string_is_ascii\n\n";
echo "ASCII\n";
echo "Short string " . $calls . " calls\n";
$phputf8 = string_is_ascii_phputf8($ascii_s, $calls);
$mb = string_is_ascii_mb($ascii_s, $calls);
$php = string_is_ascii_php($ascii_s, $calls);
echo "phputf8: " . f($phputf8) . "\n";
echo "multibyte: " . f($mb) . "\n";
echo "php: " . f($php) . "\n";
echo "Compared to phputf8: " . ($phputf8/$php) . "\n";
echo "Compared to multibyte: " . ($mb/$php) . "\n";
echo "\n\n";
echo "Medium string " . $calls . " calls\n";
$phputf8 = string_is_ascii_phputf8($ascii_m, $calls);
$mb = string_is_ascii_mb($ascii_m, $calls);
$php = string_is_ascii_php($ascii_m, $calls);
echo "phputf8: " . f($phputf8) . "\n";
echo "multibyte: " . f($mb) . "\n";
echo "php: " . f($php) . "\n";
echo "Compared to phputf8: " . ($phputf8/$php) . "\n";
echo "Compared to multibyte: " . ($mb/$php) . "\n";
echo "\n\n";
echo "Long string " . $calls . " calls\n";
$phputf8 = string_is_ascii_phputf8($ascii_l, $calls);
$mb = string_is_ascii_mb($ascii_l, $calls);
$php = string_is_ascii_php($ascii_l, $calls);
echo "phputf8: " . f($phputf8) . "\n";
echo "multibyte: " . f($mb) . "\n";
echo "php: " . f($php) . "\n";
echo "Compared to phputf8: " . ($phputf8/$php) . "\n";
echo "Compared to multibyte: " . ($mb/$php) . "\n";
echo "\n\n\n\n";
echo "UTF-8\n";
echo "Short string " . $calls . " calls\n";
$phputf8 = string_is_ascii_phputf8($utf8_s, $calls);
$mb = string_is_ascii_mb($utf8_s, $calls);
$php = string_is_ascii_php($utf8_s, $calls);
echo "phputf8: " . f($phputf8) . "\n";
echo "multibyte: " . f($mb) . "\n";
echo "php: " . f($php) . "\n";
echo "Compared to phputf8: " . ($phputf8/$php) . "\n";
echo "Compared to multibyte: " . ($mb/$php) . "\n";
echo "\n\n";
echo "Medium string " . $calls . " calls\n";
$phputf8 = string_is_ascii_phputf8($utf8_m, $calls);
$mb = string_is_ascii_mb($utf8_m, $calls);
$php = string_is_ascii_php($utf8_m, $calls);
echo "phputf8: " . f($phputf8) . "\n";
echo "multibyte: " . f($mb) . "\n";
echo "php: " . f($php) . "\n";
echo "Compared to phputf8: " . ($phputf8/$php) . "\n";
echo "Compared to multibyte: " . ($mb/$php) . "\n";
echo "\n\n";
echo "Long string " . $calls . " calls\n";
$phputf8 = string_is_ascii_phputf8($utf8_l, $calls);
$mb = string_is_ascii_mb($utf8_l, $calls);
$php = string_is_ascii_php($utf8_l, $calls);
echo "phputf8: " . f($phputf8) . "\n";
echo "multibyte: " . f($mb) . "\n";
echo "php: " . f($php) . "\n";
echo "Compared to phputf8: " . ($phputf8/$php) . "\n";
echo "Compared to multibyte: " . ($mb/$php) . "\n";
string_is_ascii
ASCII
Short string 1000 calls
phputf8: 0.0021
multibyte: 0.0010
php: 0.0002
Compared to phputf8: 13.389984825493
Compared to multibyte: 6.1487101669196
Medium string 1000 calls
phputf8: 0.0681
multibyte: 0.0058
php: 0.0009
Compared to phputf8: 76.815591397849
Compared to multibyte: 6.5405913978495
Long string 1000 calls
phputf8: 3.2911
multibyte: 0.2579
php: 0.0370
Compared to phputf8: 89.004016970572
Compared to multibyte: 6.9742088566786
UTF-8
Short string 1000 calls
phputf8: 0.0011
multibyte: 0.0011
php: 0.0001
Compared to phputf8: 7.8621908127208
Compared to multibyte: 7.9010600706714
Medium string 1000 calls
phputf8: 0.0090
multibyte: 0.0036
php: 0.0002
Compared to phputf8: 37.832335329341
Compared to multibyte: 14.90618762475
Long string 1000 calls
phputf8: 0.0036
multibyte: 0.1282
php: 0.0002
Compared to phputf8: 19.607512953368
Compared to multibyte: 696.46113989637
@hakre
Copy link

hakre commented Jun 3, 2013

I'd say the regex pattern is not optimal nor is invoking it via another function:

function string_is_ascii_phputf8($string, $c)
{
    $i = 0;
    $t = microtime(TRUE);
    while($i < $c) {
        $value = preg_match('/^[\x00-\x7F]*$/', $string);
        ++$i;
    }
    $tmp = microtime(TRUE) - $t;

    return $tmp;
}

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