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

时间:2009-10-24 19:43:29

标签: php setvalue benchmarking

我试图找出最快的方法(在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';

无论如何,我想知道在这里是否还有更多我不知道哪些方法可能不仅工作得更快 - 但也可能产生奇怪的结果。另一件事是,如果这可以证明成功完全使用整数 - 那么其他类型如字符串和浮点数也应该有效。

:UPDATE:

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

//Float
(is_scalar($value) ? floatval($value) : 0);
settype($value, 'float');

4 个答案:

答案 0 :(得分:4)

我猜你是在质疑纯粹的理论兴趣,因为在这种特殊情况下,速度差异在实践中并不重要。

让我们来看看php源代码

intval http://lxr.php.net/source/php-src/ext/standard/type.c#142

settype http://lxr.php.net/source/php-src/ext/standard/type.c#95

正如您所看到的,两个函数都使用相同的convert_to_long例程(后者又减少到库调用strtol)。 settype包含(一个很小的)将第二个参数与类型字符串进行比较的开销,所以它应该稍微慢一些。

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

答案 1 :(得分:1)

我们采取一个简单的基准:

<?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()

答案 2 :(得分:0)

除非你计划测试数以亿计的价值,否则不应该有任何实际的速度差异。存在的任何东西都很小,并不会真正影响任何东西。

答案 3 :(得分:0)

直接(类型)投射是最快的。这是我现在使用的代码。

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