255
votes

Using PHP, what's the fastest way to convert a string like this: "123" to an integer?

Why is that particular method the fastest? What happens if it gets unexpected input, such as "hello" or an array?

8
well if it doesn't hurt (readability), why not do things in the most efficient way possible?nickf
If it doesn't hurt speed, why not do things in the most readable way possible?Andy Lester
@Andy, look at the benchmark tests below. The difference between (int) and intval() can be over 400%!nickf
fastest matters because speed matters for user experience. When you have a lot of operations going on, you want to have them FAST!philipp
without kicking a dead horse, I'd also say that the question of speed vs readability is irrelevant in this case, because the question was tagged under optimization. The reason for wanting speed in a question tagged under optimization is self explanatory.totallyNotLizards

8 Answers

374
votes

I've just set up a quick benchmarking exercise:

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

On average, calling intval() is two and a half times slower, and the difference is the greatest if your input already is an integer.

I'd be interested to know why though.


Update: I've run the tests again, this time with coercion (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: I've just come across a slightly unexpected behaviour which you should be aware of when choosing one of these methods:

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

Tested using PHP 5.3.1

35
votes

I personally feel casting is the prettiest.

$iSomeVar = (int) $sSomeOtherVar;

Should a string like 'Hello' be sent, it will be cast to integer 0. For a string such as '22 years old', it will be cast to integer 22. Anything it can't parse to a number becomes 0.

If you really do NEED the speed, I guess the other suggestions here are correct in assuming that coercion is the fastest.

15
votes

Run a test.

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

This was a test that ran each scenario 10,000,000 times. :-)

Co-ercion is 0 + "123"

Casting is (integer)"123"

I think Co-ercion is a tiny bit faster. Oh, and trying 0 + array('123') is a fatal error in PHP. You might want your code to check the type of the supplied value.

My test code is below.


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

You can simply convert long string into integer by using FLOAT

$float = (float)$num;

Or if you want integer not floating val then go with

$float = (int)$num;

For ex.

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

integer excract from any string

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

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

//$out ='1231233';

4
votes

More ad-hoc benchmark results:

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

Ran a benchmark, and it turns out the fastest way of getting a real integer (using all the available methods) is

$foo = (int)+"12.345";

Just using

$foo = +"12.345";

returns a float.