web-dev-qa-db-fra.com

Le moyen le plus rapide de convertir une chaîne en entier dans PHP

En PHP, quel est le moyen le plus rapide de convertir une chaîne comme celle-ci: "123" en un entier?

Pourquoi cette méthode particulière est-elle la plus rapide? Que se passe-t-il s'il y a une entrée inattendue, telle que "hello" ou un tableau?

247
nickf

Je viens de mettre en place un exercice d'évaluation rapide:

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%)

En moyenne, appeler intval () est deux fois et demie plus lent, et la différence est la plus grande si votre entrée est déjà un entier.

Je serais intéressé de savoir pourquoi cependant.


Mise à jour: j'ai refait les tests, cette fois avec contrainte (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   |
|-----------------|------------|-----------|-----------|

Addendum: Je viens de rencontrer un comportement légèrement inattendu dont vous devez être conscient lorsque vous choisissez l'une de ces méthodes:

$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)

Testé avec PHP 5.3.1

369
nickf

Personnellement, je pense que le casting est la plus jolie.

$iSomeVar = (int) $sSomeOtherVar;

Si une chaîne telle que "Hello" est envoyée, elle sera convertie en entier 0. Pour une chaîne telle que "22 ans", elle sera convertie en entier 22. Tout ce qui ne peut pas être analysé en nombre devient 0.

Si vous AVEZ BESOIN de la vitesse, les autres suggestions suggèrent que la contrainte est la plus rapide.

34
Rexxars

Lancer un test.

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

Ce test a exécuté chaque scénario 10 000 000 fois. :-)

La coercion est 0 + "123"

Le casting est (integer)"123"

Je pense que la coercion est un peu plus rapide. Oh, et essayer de 0 + array('123') est une erreur fatale en PHP. Vous voudrez peut-être que votre code vérifie le type de la valeur fournie.

Mon code de test est ci-dessous.


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
staticsan

Vous pouvez simplement convertir une longue chaîne en entier en utilisant FLOAT

$float = (float)$num;

Ou si vous voulez un val entier non flottant, alors allez avec

$float = (int)$num;

Par ex.

(int)   "1212.3"   = 1212 
(float) "1212.3"   = 1212.3
9
Nishchit Dhanani
$int = settype("100", "integer"); //convert the numeric string to int
7
Elric Wamugu

extrait entier de n'importe quelle chaîne

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

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

// $ out = '1231233';

7
Developer

Plus de résultats de référence 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
Daniel

A atteint un repère, et il s’avère que le moyen le plus rapide d’obtenir un entier réel (en utilisant toutes les méthodes disponibles) est

$foo = (int)+"12.345";

Juste en utilisant

$foo = +"12.345";

renvoie un float.

4
Andrew Plank