在PHP中将字符串转换为整数的最快方法


251

使用PHP,将这样的字符串转换为"123"整数的最快方法是什么?

为什么该特定方法最快?如果它收到意外的输入,例如"hello"或数组,会发生什么?


12
如果它不影响(可读性),那么为什么不以最有效的方式进行处理呢?
尼克

19
如果不影响速度,为什么不以最可读的方式处理事情呢?
安迪·莱斯特

4
@Andy,请看下面的基准测试。(int)和之间的差异intval()可以超过400%!
尼克

6
最快很重要,因为速度对用户体验至关重要。当您进行大量操作时,您希望它们快!
菲利普

13
在不踢硬汉的情况下,我还要说在这种情况下,速度与可读性的问题无关紧要,因为该问题是在优化条件下标记的。在优化条件下标记的问题中需要速度的原因是不言而喻的。
totallyNotLizards 2012年

Answers:


371

我刚刚进行了快速基准测试:

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

平均而言,调用intval()的速度要慢两倍半,并且如果您的输入已经是整数,则相差最大。

我想知道为什么


更新:我再次使用强制性进行测试 (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   |
|-----------------|------------|-----------|-----------|

附录:我刚遇到一种意想不到的行为,选择以下一种方法时应注意:

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

使用PHP 5.3.1测试


9
这可能与intval()调用函数调用有关,而强制类型转换直接在解释器的表达式计算器中处理。这也可能是强制转换更快的原因。
staticsan

10
您的强制示例可以通过使用php鲜为人知的一元加运算符来进一步简化。$ x + 0-> + $ x
Ozzy

@Ozzy太棒了。谢谢你的提示!+"15" == 15
caiosm1005

1
@John因为他在第一个代码中仅测试了两种情况,(int)并且intval并且在每对中给出%on intval,所以基本情况必须为(int)。但是,您有一个很好的观点,那就是如果他这么明确地说出话会更清楚,尤其是自从他后来添加了第三种情况以来!
制造商史蒂夫(Steve)2015年

2
在更新的PHP版本中是否对此结果有任何更改?
Artyom

34

我个人觉得铸造是最漂亮的。

$iSomeVar = (int) $sSomeOtherVar;

如果发送类似“ Hello”的字符串,则将其强制转换为整数0。对于诸如“ 22岁”的字符串,将其强制转换为整数22。任何无法解析为数字的值都将变为0。

如果您确实需要速度,我想这里的其他建议都是正确的,假设强制是最快的。


7
有趣的是,数组被强制转换为1. go Figure。
尼克

2
@nickf并非如此-也可以将其强制转换为0。它将布尔值(true | false)转换为整数-'false'= 0,'true'=1。如果数组100%为空,则该数组为false;即使包含空数据,也为true。字符串或NULL值。如果将空数组转换为整数,则它将变为0。(是的,我知道这个很旧!)
Super Cat

15

运行测试。

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

这是对每个方案运行10,000,000次的测试。:-)

强制是 0 + "123"

正在投射 (integer)"123"

我认为Co-ercion快一点。哦,尝试0 + array('123')是PHP中的致命错误。您可能希望代码检查提供的值的类型。

我的测试代码如下。


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

我添加settype了此测试,并使用PHP 7运行了它。Cast的表现略显领先,并且在所有方面都实现了很大的性能提升:字符串强制:1.9255340099335字符串强制转换:1.5142338275909字符串集类型:4.149735212326字符串失败强制:1.2346560955048字符串失败强制转换:1.3967711925507字符串失败settype:4.149735212326
bstoney,2016年

9

您可以使用FLOAT简单地将长字符串转换为整数

$float = (float)$num;

或者,如果您想让整数不浮动val,请选择

$float = (int)$num;

对于前。

(int)   "1212.3"   = 1212 
(float) "1212.3"   = 1212.3

1
??如果您想要一个整数,为什么不使用(int)?可能确实是这样,如果字符串包含一个整数,那么(float)它将返回一个非常类似于整数的值(即使其内部类型可能是float),但是如果规范要返回一个整数值,那么为什么要这样做呢? ?假设传入的字符串是“ 1.3”?你不会得到一个整数。另外,为了将来有人阅读该代码,您应该说出您的意思。如果您的意思是“它应该是整数”,请说(int),不是(float)
ToolmakerSteve

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

3
相信一定要提供一些参考或证明!
Mehran 2012年

如果该语句有效,则$ int在此处实际上是一个布尔值,但是由于settype()的第一个参数是通过引用传递的,因此它不会是boolean值。
2014年

7

任何字符串的整数

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

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

// $ out ='1231233';


您是最好的最好的!我已经花了几个小时将一些var从json数据字符串转换为整数,只有您的方法有所帮助!谢谢!
卡姆尼布拉2015年

4

更多临时基准测试结果:

$ 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

最好在每个循环中将被测试的语句写成10x,这样时间就不会被循环开销所支配。例如{ $i = +"-11"; $i = +"-11"; $i= +"-11"; $i= +"-11"; ... }"-11"直接使用文字值也是有风险的,除非您确定该语言在编译时不会做某些工作。对于像PHP这样的动态语言来说可能还可以,但是如果测试其他语言的公式,我会提到以供将来参考。$x = "-11"在测试循环之前更安全地设置变量,然后使用它。这样内部代码是$i =+$x
ToolmakerSteve 2015年

4

运行一个基准,结果发现(使用所有可用方法)获取整数的最快方法是

$foo = (int)+"12.345";

只是使用

$foo = +"12.345";

返回一个浮点数。


2
这比简单要快(int)"12.345"吗?快百分之几?
制造商
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.