簡體   English   中英

確定 PHP 中是否存在數組鍵有什么更快更好的方法?

[英]What's quicker and better to determine if an array key exists in PHP?

考慮這兩個例子......

$key = 'jim';

// example 1
if (isset($array[$key])) {
    // ...
}

// example 2    
if (array_key_exists($key, $array)) {
    // ...
}

我有興趣知道這些是否更好。 我一直使用第一個,但在這個站點上看到很多人使用第二個示例。

那么,哪個更好? 快點? 更明確的意圖?

isset()更快,但它與array_key_exists()不同。

array_key_exists()純粹檢查鍵是否存在,即使值為NULL

而如果鍵存在且值為NULL ,則isset()將返回false

如果你對我最近做過的一些測試感興趣:

https://stackoverflow.com/a/21759158/520857

概括:

| Method Name                              | Run time             | Difference
=========================================================================================
| NonExistant::noCheckingTest()            | 0.86004090309143     | +18491.315775911%
| NonExistant::emptyTest()                 | 0.0046701431274414   | +0.95346080503016%
| NonExistant::isnullTest()                | 0.88424181938171     | +19014.461681183%
| NonExistant::issetTest()                 | 0.0046260356903076   | Fastest
| NonExistant::arrayKeyExistsTest()        | 1.9001779556274      | +209.73055713%

嗯,主要區別在於isset()不會為對應於 null 值的數組鍵返回true ,而array_key_exists()會。

運行一個小型基准測試表明isset()它更快,但它可能並不完全准確。

通過 Php 7 可以使用Null 合並運算符

已添加 null 合並運算符 (??) 作為語法糖,用於需要將三元與 isset() 結合使用的常見情況。 如果存在且不是 NULL,則返回其第一個操作數; 否則返回第二個操作數。

因此,現在您可以指定一個默認值,以防該值為 null 或該鍵不存在:

$var = $array[$key] ?? 'default value'

我想在這個問題上加上我的 2 美分,因為我錯過了一個中間出路。

如前所述, isset()將評估密鑰的值,因此如果該值為null ,它將返回false ,其中array_key_exists()將僅檢查密鑰是否存在於數組中。


我使用 PHP 7 運行了一個簡單的基准測試,顯示的結果是完成迭代所花費的時間:

$a = [null, true];

isset($a[0])                            # 0.3258841  - false
isset($a[1])                            # 0.28261614 - true
isset($a[2])                            # 0.26198816 - false

array_key_exists(0, $a)                 # 0.46202087 - true
array_key_exists(1, $a)                 # 0.43063688 - true
array_key_exists(2, $a)                 # 0.37593913 - false

isset($a[0]) || array_key_exists(0, $a) # 0.66342998 - true
isset($a[1]) || array_key_exists(1, $a) # 0.28389215 - true
isset($a[2]) || array_key_exists(2, $a) # 0.55677581 - false

array_key_isset(0, $a)                  # 1.17933798 - true
array_key_isset(1, $a)                  # 0.70253706 - true
array_key_isset(2, $a)                  # 1.01110005 - false

我已將此自定義 function 的結果添加到此基准測試中以完成:

function array_key_isset($k, $a){
    return isset($a[$k]) || array_key_exists($k, $a);
}

正如所見並且已經告訴isset()是最快的方法,但如果值為null ,它可以返回 false 。 這可能會產生不需要的結果,如果是這種情況,通常應該使用array_key_exists()

但是有一個中間出路,那就是使用isset() || array_key_exists() isset() || array_key_exists() 此代碼通常使用更快的 function isset()並且如果isset()僅返回 false 則使用array_key_exists()進行驗證。 如上表所示,它與直接調用isset()一樣快。

是的,在 function 中編寫和包裝它會更慢一些,但要容易得多。 如果您需要它來提高性能、檢查大數據等,請將其全部寫出來,否則如果它是 1 次使用,那么 function array_key_isset()中的非常小的開銷可以忽略不計。

您將閱讀到與php.net不同的地方:

對於對應於 NULL 值的數組鍵,isset() 不會返回 TRUE,而 array_key_exists() 會。

一個非常非正式的測試顯示array_key_exists()isset()慢大約 2.5 倍

結合isset()is_null()對其他函數提供最佳性能,例如: array_key_exists()isset()isset() + array_key_exists()is_null()isset() + is_null() ,這里唯一的問題是function 不僅會在密鑰不存在時返回 false,而且即使密鑰存在並且具有 null 值。

基准腳本:

<?php
  $a = array('a' => 4, 'e' => null)

  $s = microtime(true); 
  for($i=0; $i<=100000; $i++) { 
    $t = (isset($a['a'])) && (is_null($a['a'])); //true 
    $t = (isset($a['f'])) && (is_null($a['f'])); //false
    $t = (isset($a['e'])) && (is_null($a['e']));; //false 
  } 

  $e = microtime(true); 
  echo 'isset() + is_null() : ' , ($e-$s)."<br><br>";
?>

信用https://web.archive.org/web/20140222232248/zomeoff.com/php-fast-way-to-determine-a-key-elements-existance-in-an-array/

至於“更快”:試試看(我的錢在array_key_exists()上,但我現在不能嘗試)。

至於“意圖更清晰”: array_key_exists()

顯然第二個例子的意圖更清楚,這是毫無疑問的。 要弄清楚示例 #1 的作用,您需要熟悉 PHP 的變量初始化特性——然后您會發現它對 null 值的作用不同,等等。

至於哪個更快-我不打算推測-在您的 PHP 版本上緊密循環運行幾十萬次,您會發現:)

我想補充一點,您還可以使用 isset 搜索具有唯一元素的數組。 它比使用 in_array、array_search 或 array_key_exists 快得多。 您可以使用 array_flip 翻轉數組並使用 isset 檢查數組中是否存在值。

<?php

$numbers = [];
for ($i = 0; $i < 1000000; $i++) {
    $numbers[] = random_int("9000000000", "9999999999");
}

function evaluatePerformance($name, $callback)
{
    global $numbers;
    $timeStart = microtime(true);

    $result = $callback("1234567890", $numbers) ? 'true' : 'false';

    $timeEnd = microtime(true);
    $executionTime =  number_format($timeEnd - $timeStart, 9);

    echo  "{$name} result is {$result} and it took {$executionTime} seconds. <br>";
}

// Took 0.038895845 seconds.
evaluatePerformance("in_array", function ($needle, $haystack) {
    return in_array($needle, $haystack);
});

// Took 0.035454988 seconds.
evaluatePerformance("array_search", function ($needle, $haystack) {
    return array_search($needle, $haystack);
});

$numbers = array_flip($numbers);

// Took 0.000024080 seconds.
evaluatePerformance("array_key_exists", function ($needle, $haystack) {
    return array_key_exists($needle, $haystack);
});

// Took 0.000013113 seconds.
evaluatePerformance("isset", function ($needle, $haystack) {
    return isset($haystack[$needle]);
});

您的代碼isset($array[$i]) || $array[$i] === null isset($array[$i]) || $array[$i] === null在每種情況下都會返回 true,即使鍵不存在(並產生未定義的索引通知)。 為了獲得最佳性能,您想要的是if (isset($array[$key]) || array_key_exists($key,$array)){doWhatIWant();}

暫無
暫無

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

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