Najszybszy sposób konwersji ciągu na liczbę całkowitą w PHP

Używając PHP, jaki jest najszybszy sposób na przekonwertowanie takiego ciągu znaków: "123" na liczbę całkowitą?

Dlaczego ta metoda jest najszybsza? Co się stanie, jeśli otrzyma nieoczekiwane dane wejściowe, takie jak "hello" lub tablica?
Author: billjamesdev, 2008-10-27

8 answers

Właśnie ustawiłem szybkie ćwiczenie benchmarkingowe:

Function             time to run 1 million iterations
--------------------------------------------
(int) "123":                0.55029
intval("123"):              1.0115  (183%)

(int) "0":                  0.42461
intval("0"):                0.95683 (225%)

(int) int:                  0.1502
intval(int):                0.65716 (438%)

(int) array("a", "b"):      0.91264
intval(array("a", "b")):    1.47681 (162%)

(int) "hello":              0.42208
intval("hello"):            0.93678 (222%)

Przeciętnie wywołanie intval() jest dwa i pół razy wolniejsze, a różnica jest największa, jeśli Dane wejściowe są już liczbą całkowitą.

Chciałbym wiedzieć, dlaczego.

Update: ponownie przeprowadziłem testy, tym razem z przymusem (0 + $var)

| INPUT ($x)      |  (int) $x  |intval($x) |  0 + $x   |
|-----------------|------------|-----------|-----------|
| "123"           |   0.51541  |  0.96924  |  0.33828  |
| "0"             |   0.42723  |  0.97418  |  0.31353  |
| 123             |   0.15011  |  0.61690  |  0.15452  |
| array("a", "b") |   0.8893   |  1.45109  |  err!     |
| "hello"         |   0.42618  |  0.88803  |  0.1691   |
|-----------------|------------|-----------|-----------|

Dodatek: właśnie natknąłem się na nieco nieoczekiwane zachowanie, o którym powinieneś wiedzieć wybierając jedno z tych metody:

$x = "11";
(int) $x;      // int(11)
intval($x);    // int(11)
$x + 0;        // int(11)

$x = "0x11";
(int) $x;      // int(0)
intval($x);    // int(0)
$x + 0;        // int(17) !

$x = "011";
(int) $x;      // int(11)
intval($x);    // int(11)
$x + 0;        // int(11) (not 9)

testowane przy użyciu PHP 5.3.1

 365
Author: nickf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-14 04:49:59

Osobiście uważam, że casting jest najładniejszy.

$iSomeVar = (int) $sSomeOtherVar;

Jeśli zostanie wysłany łańcuch typu 'Hello', zostanie on oddany do liczby całkowitej 0. Dla ciągu, takiego jak '22 years old', zostanie on oddany do liczby całkowitej 22. Wszystko, czego nie można przetworzyć do liczby, staje się 0.

Jeśli naprawdę potrzebujesz prędkości, myślę, że inne sugestie tutaj są poprawne, zakładając, że przymus jest najszybszy.

 33
Author: Rexxars,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-27 07:50:01

Uruchom test.

   string coerce:          7.42296099663
   string cast:            8.05654597282
   string fail coerce:     7.14159703255
   string fail cast:       7.87444186211

To był test, który przebiegał każdy scenariusz 10,000,000 razy. :-)

Co-ercion jest 0 + "123"

Casting jest (integer)"123"

Myślę, że Co-ercion jest trochę szybszy. AHA, i próba 0 + array('123') jest fatalnym błędem w PHP. Możesz chcieć, aby Twój kod sprawdzał Typ dostarczonej wartości.

Mój kod testowy jest poniżej.


function test_string_coerce($s) {
    return 0 + $s;
}

function test_string_cast($s) {
    return (integer)$s;
}

$iter = 10000000;

print "-- running each text $iter times.\n";

// string co-erce
$string_coerce = new Timer;
$string_coerce->Start();

print "String Coerce test\n";
for( $i = 0; $i < $iter ; $i++ ) {
    test_string_coerce('123');
}

$string_coerce->Stop();

// string cast
$string_cast = new Timer;
$string_cast->Start();

print "String Cast test\n";
for( $i = 0; $i < $iter ; $i++ ) {
    test_string_cast('123');
}

$string_cast->Stop();

// string co-erce fail.
$string_coerce_fail = new Timer;
$string_coerce_fail->Start();

print "String Coerce fail test\n";
for( $i = 0; $i < $iter ; $i++ ) {
    test_string_coerce('hello');
}

$string_coerce_fail->Stop();

// string cast fail
$string_cast_fail = new Timer;
$string_cast_fail->Start();

print "String Cast fail test\n";
for( $i = 0; $i < $iter ; $i++ ) {
    test_string_cast('hello');
}

$string_cast_fail->Stop();

// -----------------
print "\n";
print "string coerce:          ".$string_coerce->Elapsed()."\n";
print "string cast:            ".$string_cast->Elapsed()."\n";
print "string fail coerce:     ".$string_coerce_fail->Elapsed()."\n";
print "string fail cast:       ".$string_cast_fail->Elapsed()."\n";


class Timer {
    var $ticking = null;
    var $started_at = false;
    var $elapsed = 0;

    function Timer() {
        $this->ticking = null;
    }

    function Start() {
        $this->ticking = true;
        $this->started_at = microtime(TRUE);
    }

    function Stop() {
        if( $this->ticking )
            $this->elapsed = microtime(TRUE) - $this->started_at;
        $this->ticking = false;
    }

    function Elapsed() {
        switch( $this->ticking ) {
            case true: return "Still Running";
            case false: return $this->elapsed;
            case null: return "Not Started";
        }
    }
}
 15
Author: staticsan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-27 05:51:33

Można po prostu przekonwertować długi łańcuch na liczbę całkowitą za pomocą FLOAT

$float = (float)$num;

Lub jeśli chcesz integer nie floating val to idź z

$float = (int)$num;

Dla ex.

(int)   "1212.3"   = 1212 
(float) "1212.3"   = 1212.3
 9
Author: Nishchit Dhanani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-21 11:34:29
$int = settype("100", "integer"); //convert the numeric string to int
 7
Author: Elric Wamugu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-03 14:50:37

Liczba całkowita z dowolnego ciągu

$in = ' tel.123-12-33';

preg_match_all('!\d+!', $in, $matches);
$out =  (int)implode('', $matches[0]);

//$out = '1231233';

 7
Author: Greg Hmhmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 05:14:13

Więcej wyników porównawczych ad-hoc:

$ time php -r 'for ($x = 0;$x < 999999999; $x++){$i = (integer) "-11";}'     

real    2m10.397s
user    2m10.220s
sys     0m0.025s

$ time php -r 'for ($x = 0;$x < 999999999; $x++){$i += "-11";}'              

real    2m1.724s
user    2m1.635s
sys     0m0.009s

$ time php -r 'for ($x = 0;$x < 999999999; $x++){$i = + "-11";}'             

real    1m21.000s
user    1m20.964s
sys     0m0.007s
 4
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-30 07:38:37

Uruchomił benchmark i okazało się, że najszybszym sposobem uzyskania prawdziwej liczby całkowitej (przy użyciu wszystkich dostępnych metod) jest

$foo = (int)+"12.345";

Po prostu używam

$foo = +"12.345";

Zwraca float.

 4
Author: Andrew Plank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-10 11:31:02