代码之家  ›  专栏  ›  技术社区  ›  Xeoncross

使用settype()和*val()函数的最快PHP类型?

  •  2
  • Xeoncross  · 技术社区  · 15 年前

    我试图找出最快的方法(在php 5中)来检查一个值是否是 type I need 是的。我创建了两行代码,它们都做相同的事情。问题是我无法根据基准找出哪一个最快。

    (is_scalar($value) ? intval($value) : 0);
    settype($value, 'integer');
    

    我创建了下面的测试代码,但我只有自己的PC(core2quad+xp 32bit+php5.2.5)和一个Dreamhost帐户来测试它,这两个帐户对这段代码显示的时间差不多相同。

    $array = array(
        'false' => FALSE,
        'false2'=> 0,
        'false3'=> '0',
        'false4'=> 'FALSE',
        'true'  => TRUE,
        'true2' => 1,
        'true3' => '1',
        'true4' => 'TRUE',
    
        'char'  => chr(250),
        'char2' => chr(10),
        'utf'   => 0xF0,
        'utf1'  => 0xFE,
    
        'number' => '452.5435',
        'number2' => '-3948.33e2',
        'number3' => -343.54,
        'number4' => 99.999,
        'number5' => '3jk439fjk23945t324098523.349fj324r',
    
        'int'   => 2323,
        'int2'  => '2345',
        'int3'  => '0',
        'int4'  => array(),
        'int5'  => '39582347823908270983249078530793249802357846t890234879023490785',
        'int6'  => 3895732890543789324890123467548093248976123890548793289073246789458901234,
    
        'object3' => new SimpleXMLElement('<xml></xml>'),
    
        'array' => array(),
        'array2' => array('hello'),
        'array3' => array(3,54,21,0),
        'array4' => array(0.2)
    );
    
    
    $start = microtime(TRUE);
    
    for($x=0;$x<10000;$x++) {
        foreach( $array as $value ) {
            (is_scalar($value) ? intval($value) : 0);
            //settype($value, 'integer');
        }
    }
    
    print (microtime(TRUE) - $start). ' seconds';
    

    不管怎样,我想知道这里是否还有更多我遗漏的方法,这些方法中的哪一种不仅工作得更快,而且可能产生奇怪的结果。另一件事是,如果用ints证明这是完全成功的,那么其他类型(如字符串和浮点)也应该有效。

    更新:

    我刚刚对float类型测试了这些方法,发现settype()比floatval()(0.21秒)慢(.28秒)。所以这个问题的答案可能只对int类型有效。

    //Float
    (is_scalar($value) ? floatval($value) : 0);
    settype($value, 'float');
    
    4 回复  |  直到 11 年前
        1
  •  4
  •   user187291    15 年前

    我想你的要求纯粹是出于理论上的兴趣,因为在这个特殊的情况下,速度的差异在实践中并不重要。

    让我们来看看PHP源代码

    字符串变量 http://lxr.php.net/source/php-src/ext/standard/type.c#142

    设置类型 http://lxr.php.net/source/php-src/ext/standard/type.c#95

    如您所见,两个函数都使用相同的convert_to_long例程(这反过来又减少到库调用strtol)。settype包含(一个很小的)将第二个参数与类型字符串进行比较的开销,因此它应该稍微慢一点。

    最快的方法是使用(int)cast,因为它不涉及函数调用操作码,而是由vm直接执行。

        2
  •  1
  •   Alexander Palamarchuk    11 年前

    让我们以一个简单的基准:

    <?php
    $y = "45678912";
    
    $time_start = microtime(true);
    for ($i=0; $i<500000; $i++) {
        $x = $y;
        $x = intval($x);
    }
    echo "\nintval: " . (microtime(true) - $time_start) . " sec.";
    
    $time_start = microtime(true);
    for ($i=0; $i<500000; $i++) {
        $x = $y;
        $x = (int)$x;
    }
    echo "\n(int): " . (microtime(true) - $time_start) . " sec.";
    
    $time_start = microtime(true);
    for ($i=0; $i<500000; $i++) {
        $x = $y;
        settype($x, 'int');
    }
    echo "\nsettype: " . (microtime(true) - $time_start) . " sec.\n";
    

    我在64位Ubuntu上的结果:

    intval: 0.47533583641052 sec.
    (int): 0.19618892669678 sec.
    settype: 0.51951289176941 sec.
    

    在长整数上,图像是相似的。所以(int)是最好的,但是没有真正的理由使用intval()而不是settype()。

        3
  •  0
  •   Jani Hartikainen    15 年前

    除非你打算测试数不清的值,否则不应该有任何实际的速度差。任何存在的事物都是如此之小,它不会真正影响任何事物。

        4
  •  0
  •   user187291    13 年前

    直接(型)铸造是最快的。这是我现在使用的代码。

    (is_scalar($int) && is_numeric($int) ? (int) $int : 0)