最快的 PHP 类型与 settype() 和 *val() 函数的比较?

发布于 2024-08-08 15:34:19 字数 1958 浏览 6 评论 0原文

我试图找出最快的方法(在 PHP 5 中)来检查值是否为 我需要的类型。我创建了两行代码,它们都执行相同的操作。问题是我无法根据基准确定哪个最快。

(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';

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

:更新:

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

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

I am trying to figure out the fastest way (in PHP 5) to check that a value is the type I need it to be. I created two lines of code which both do the same thing. The problem is that I can't figure out which is fastest based off of benchmarks.

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

I created the following test code but I don't have any more than my own PC (Core2Quad + XP 32bit + php5.2.5) and a dreamhost account to test it with - both of which show about the same times for this code.

$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';

Anyway, I was wondering if there might be more here that I am missing as to which of these methods might not only work faster - but might yield odd results as well. Another thing is that should this prove success full with ints - then other types such as strings and floats should also work.

:UPDATE:

I just tested these methods against the float type and found that settype() was slower (.28 sec) vs floatval() (.21 sec). So the answer to this question may only be valid for the int type.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

记忆之渊 2024-08-15 15:34:19

我想你问这个问题纯粹是出于理论兴趣,因为在这种特殊情况下的速度差异在实践中不能被认为是重要的。

让我们看一下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直接执行。

i guess you're asking out of pure theoretical interest, because the speed differences in this particular case cannot be considered important in practice.

let's take a look into php source code

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

as you can see, both function use the same convert_to_long routine (which in turn reduces to the library call strtol). settype includes (a tiny) overhead of comparing the second argument with a type string, so it should be slightly slower.

the fastest method would be to use (int) cast, because it doesn't involve a function call opcode, but executed directly by VM.

黯淡〆 2024-08-15 15:34:19

让我们进行一个简单的基准测试:

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

Let's take a simple benchmark:

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

My results on 64bit Ubuntu:

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

On long integers the picture is similar. So (int) is the best, but there's no real reason to use intval() instead of settype()

祁梦 2024-08-15 15:34:19

除非您计划测试无数个值,否则不应该有任何实际的速度差异。任何存在的东西都很小,不会真正影响任何事情。

Unless you're planning on testing a bazillion values, there should not be any practical speed difference. Any that exists is so small it doesn't really affect anything.

何以心动 2024-08-15 15:34:19

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

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

Direct (type) casting is the fastest. Here is the code I use now.

(is_scalar($int) && is_numeric($int) ? (int) $int : 0)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文