Domanda

Usando PHP, qual è il modo più veloce per convertire una stringa come questa: " 123 " in un numero intero?

Perché quel particolare metodo è il più veloce? Cosa succede se riceve input imprevisti, come " hello " o un array?

È stato utile?

Soluzione

Ho appena organizzato un rapido esercizio di benchmarking:

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

In media, chiamare intval () è due volte e mezzo più lento e la differenza è maggiore se il tuo input è già un numero intero.

Sarei interessato a sapere perché però.


Aggiornamento: ho eseguito di nuovo i test, questa volta con la coercizione (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: ho appena riscontrato un comportamento leggermente inaspettato di cui dovresti essere consapevole quando scegli uno di questi metodi:

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

Testato utilizzando PHP 5.3.1

Altri suggerimenti

Personalmente ritengo che il casting sia il più bello.

$iSomeVar = (int) $sSomeOtherVar;

Se viene inviata una stringa come 'Hello', verrà lanciata sull'intero 0. Per una stringa come '22 anni ', verrà lanciata sull'intero 22. Tutto ciò che non è in grado di analizzare in un numero diventa 0.

Se hai davvero BISOGNO della velocità, immagino che gli altri suggerimenti qui siano corretti nel presupporre che la coercizione sia la più veloce.

Esegui un test.

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

Questo è stato un test che ha eseguito ogni scenario 10.000.000 di volte. : -)

La coercizione è 0 + " 123 "

Il casting è (integer)"123"

Penso che Co-ercion sia un po 'più veloce. Oh, e provare 0 + array ('123') è un errore fatale in PHP. È possibile che il codice controlli il tipo di valore fornito.

Il mio codice di prova è sotto.


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";
        }
    }
}

Puoi semplicemente convertire una stringa lunga in numero intero usando FLOAT

$ float = (float) $ num;

O se vuoi che l'intero non sia mobile, vai con

$ float = (int) $ num;

Per es.

(int)   "1212.3"   = 1212 
(float) "1212.3"   = 1212.3
$int = settype("100", "integer"); //convert the numeric string to int

numero intero espulso da qualsiasi stringa

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

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

// $ out = '1231233';

Altri risultati di benchmark 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

Ha eseguito un benchmark e risulta che il modo più veloce per ottenere un numero intero reale (utilizzando tutti i metodi disponibili) è

$foo = (int)+"12.345";

Basta usare

$foo = +"12.345";

restituisce un float.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top