簡體   English   中英

將MySQL tinyint booleans(0/1)轉換為PHP布爾值(true / false)

[英]Converting MySQL tinyint booleans (0/1) to PHP booleans (true/false)

我需要重復將MySQL tinyint(1)'boolean'數據類型轉換為PHP布爾值,我一直在嘗試測試最快的方法來執行此操作。 我的數據映射如下:

  • NULL = FALSE
  • 0 =假
  • 1 =正確

環顧四個小時后,我似乎無法找到任何性能解釋/批評,所以我去嘗試自己制作一個我找到的可能解決方案。 我的代碼如下:

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秒,以便一目了然地看到縮放。 從這個測試來看,似乎最好的選擇是!空($ 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中可能出現的重大性能變化之后,我對它如何向前推進感興趣,因為競爭現在非常接近!

這似乎已在PHP的更高版本中進行了優化:

Current PHP Version: 5.6.16-2+deb.sury.org~wily+1

Did NOT EMPTY in 0.43913006782532 seconds
Did TYPECAST BOOL in 0.40566301345825 seconds
Did EQUALS TRUE in 0.42750406265259 seconds
Did NOT NOT in 0.43936395645142 seconds
Did IS NULL in 1.3173689842224 seconds

PHP 7更令人印象深刻:

Current PHP Version: 7.0.1-1+deb.sury.org~wily+2

Did NOT EMPTY in 0.21985292434692 seconds
Did TYPECAST BOOL in 0.18928909301758 seconds
Did EQUALS TRUE in 0.17465591430664 seconds
Did NOT NOT in 0.20792722702026 seconds
Did IS NULL in 0.15517687797546 seconds

類型轉換似乎是這里的最佳解決方案,涉及性能和可讀性(類似於(bool) $someVar的構造(bool) $someVar向其他開發人員傳達的意圖遠遠超過!!$someVar或其他模糊構造)。

PHP的默認活動不夠用嗎?

無恥地從手冊中刪除

轉換為布爾值

要將值顯式轉換為布爾值,請使用(bool)或(boolean)強制轉換。 但是,在大多數情況下,轉換是不必要的,因為如果運算符,函數或控件結構需要布爾參數,則會自動轉換值。

另見Type Juggling

轉換為布爾值時,以下值被視為FALSE:

the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags

每個其他值都被視為TRUE(包括任何資源)。

首先,你應該解決您的測試,你將值分配給$start0$start1 ,但隨后你檢查$start1$start2其中沒有定義后者。

一旦修復,最快的測試就是簡單的比較(你沒試過):

$answer = $start0 == 1

這是我的代碼(我從終端運行它)

<?php
echo 'Current PHP Version: ' . phpversion() . "\n\n";
$start1 = 1;
$start0 = 0;

$time_start = microtime(TRUE);
for( $i = 0 ; $i < 8500000; $i++ )
{
    $answer = $start0 == 1;
    $answer = $start1 == 1;  
}
$time_end = microtime(TRUE);
echo 'Did COMPARISON in ' . ($time_end - $time_start) . " seconds\n";

$time_start = microtime(TRUE);
for( $i = 0 ; $i < 8500000; $i++ )
{
    $answer = !empty($start0);
    $answer = !empty($start1);  
}
$time_end = microtime(TRUE);
echo 'Did NOT EMPTY in ' . ($time_end - $time_start) . " seconds\n";

/* 
   .
   .
   .
*/

這是結果

Current PHP Version: 5.4.45

Did COMPARISON in 0.60736107826233 seconds
Did NOT EMPTY in 0.75234413146973 seconds
Did TYPECAST BOOL in 0.67925190925598 seconds
Did EQUALS TRUE in 0.80053496360779 seconds
Did NOT NOT in 0.95479583740234 seconds
Did IS NULL in 2.1385459899902 seconds

您可以在此處對不同版本的PHP運行測試

https://3v4l.org/t4K5j

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM