我需要反复将MySQL tinyint(1) 'boolean'数据类型转换为PHP布尔值,并且一直在尝试测试最快的方法。我的数据映射如下:
我选择了850万次迭代,因为我通常喜欢将最快的测试尽可能接近1秒,以便一目了然地看到扩展情况。从这个测试中可以看出,最佳选择是!empty($value),而且差距非常大。
我发布这篇文章是为了分享我的发现,并看看是否有其他方法可以获得相同的结果,可能更快,或者在未来的PHP版本中会发生根本性的变化。我们目前处于5.4环境中,希望在明年将其移植到5.6,并希望最终看到php7。
在新版本的PHP中,这些方法中是否有一个不同的胜出者,或者是否有完全不同的方法可以解决这个问题?感谢您的见解!
编辑:正如所指出的那样,上面的测试是不正确的。下面是一个正确的测试,还有一个额外的选项:
- NULL = FALSE
- 0 = FALSE
- 1 = TRUE
echo 'Current PHP Version: ' . phpversion() . '<br /><br />';
$start1 = 1;
$start0 = 0;
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 8500000; $i++ )
{
$answer = !empty($start1);
$answer = !empty($start2);
}
$time_end = microtime(TRUE);
echo 'Did NOT EMPTY in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 8500000; $i++ )
{
$answer = (bool)$start1;
$answer = (bool)$start2;
}
$time_end = microtime(TRUE);
echo 'Did TYPECAST BOOL in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 8500000; $i++ )
{
$answer = $start1 == TRUE;
$answer = $start2 == TRUE;
}
$time_end = microtime(TRUE);
echo 'Did EQUALS TRUE in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 8500000; $i++ )
{
$answer = !!$start1;
$answer = !!$start2;
}
$time_end = microtime(TRUE);
echo 'Did NOT NOT in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 8500000; $i++ )
{
$answer = is_null($start1);
$answer = is_null($start2);
}
$time_end = microtime(TRUE);
echo 'Did IS NULL in ' . ($time_end - $time_start) . " seconds<br>";
我的结果如下:
Current PHP Version: 5.4.16
Did NOT EMPTY in 1.00608086586 seconds
Did TYPECAST BOOL in 2.5599420070648 seconds
Did EQUALS TRUE in 2.7039749622345 seconds
Did NOT NOT in 2.7622299194336 seconds
Did IS NULL in 4.1728219985962 seconds
我选择了850万次迭代,因为我通常喜欢将最快的测试尽可能接近1秒,以便一目了然地看到扩展情况。从这个测试中可以看出,最佳选择是!empty($value),而且差距非常大。
我发布这篇文章是为了分享我的发现,并看看是否有其他方法可以获得相同的结果,可能更快,或者在未来的PHP版本中会发生根本性的变化。我们目前处于5.4环境中,希望在明年将其移植到5.6,并希望最终看到php7。
在新版本的PHP中,这些方法中是否有一个不同的胜出者,或者是否有完全不同的方法可以解决这个问题?感谢您的见解!
编辑:正如所指出的那样,上面的测试是不正确的。下面是一个正确的测试,还有一个额外的选项:
echo 'Current PHP Version: ' . phpversion() . '<br /><br />';
$start1 = 1;
$start0 = 0;
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 14000000; $i++ )
{
$answer = $start1 == 1;
$answer = $start0 == 1;
}
$time_end = microtime(TRUE);
echo 'Did EQUALS 1 in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 14000000; $i++ )
{
$answer = (bool)$start1;
$answer = (bool)$start0;
}
$time_end = microtime(TRUE);
echo 'Did TYPECAST BOOL in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 14000000; $i++ )
{
$answer = $start1 == TRUE;
$answer = $start0 == TRUE;
}
$time_end = microtime(TRUE);
echo 'Did EQUALS TRUE in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 14000000; $i++ )
{
$answer = !!$start1;
$answer = !!$start0;
}
$time_end = microtime(TRUE);
echo 'Did NOT NOT in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 14000000; $i++ )
{
$answer = !empty($start1);
$answer = !empty($start0);
}
$time_end = microtime(TRUE);
echo 'Did NOT EMPTY in ' . ($time_end - $time_start) . " seconds<br>";
$time_start = microtime(TRUE);
for( $i = 0 ; $i < 14000000; $i++ )
{
$answer = !is_null($start1);
$answer = !is_null($start0);
}
$time_end = microtime(TRUE);
echo 'Did NOT IS NULL in ' . ($time_end - $time_start) . " seconds<br>";
这个测试给了我:
Current PHP Version: 5.4.16
Did EQUALS 1 in 1.0449228286743 seconds
Did TYPECAST BOOL in 1.0921199321747 seconds
Did EQUALS TRUE in 1.3697588443756 seconds
Did NOT NOT in 1.3729720115662 seconds
Did NOT EMPTY in 1.4694240093231 seconds
Did NOT IS NULL in 3.2058408260345 seconds
看到PHP新版本中可能会有显著的性能变化,我对它未来的表现很感兴趣,因为目前竞争非常激烈!
NULL
强制转换为false
可能会让你某天陷入严重的麻烦。"未设置"与"设置为非真"完全不同。 - tadman