PHPに配列キーが存在するかどうかを判断するのに、より迅速で優れた方法は何ですか?


157

次の2つの例を検討してください...

$key = 'jim';

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

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

これらのどちらが良いか知りたいです。私は常に最初のものを使用してきましたが、多くの人々がこのサイトで2番目の例を使用するのを見てきました。

それで、どちらが良いですか?もっと早く?より明確な意図?


いいえ、ベンチマークを実行していません。尋ねる前に持っておくべきですか?
アレックス

4
issetがまったく同じようarray_key_existsに動作することはありません。同じように動作すると思われるコード例では、キーが存在しない場合に通知をスローします。
だます

どうin_arrayですか?maettig.com/1397246220
DanMan '

1
@DanMan、in_arrayであるO(n)ことが数値ではないキーをチェックするため。あなたnが極端に小さい場合を除いて、彼らはほとんど常に遅くなるでしょう。
Pacerier 2015年

なんで$array[$key] === null
Pacerier 2017年

回答:


237

isset()は高速ですが、とは異なりarray_key_exists()ます。

array_key_exists()値がであっても、キーが存在するかどうかを純粋にチェックしますNULL

一方 isset()戻りますfalseキーが存在し、値がある場合NULL


5
issetがより速いと主張する特定のリソースはありますか?
Francesco Pasa

@Francesco Pasaちょっと考えてみてください。issetは配列検索関数ではありません。シンボルテーブル内の変数の存在をチェックするだけで、配列を反復処理しません。array_key_exists一方、指定された配列の最初の次元でキーを反復/検索します。

@Rain array_key_exists()キーが配列内にあるかどうかだけをチェックすることはかなり確実です。つまり、ハッシュテーブルであるため、検索は行われません。
Francesco Pasa

@FrancescoPasaまあ、「キーの検索」はPHPのドキュメントに書かれています。それ以外では、彼らに対する「検索」が私にとってそれが意味するものとは完全に異なる何かを意味するかどうかはわかりません。

32

最近行ったいくつかのテストに興味がある場合:

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%

重要:arrayKeyExistsタイミングが非常に間違っていることが発見された-それはキーのない値をチェックしていた-である7.1で修正されたタイミング、のためにそのリンクをたどるずっと優れています。(ポプラは、そのテストをやり直している場合だろうにも、以前のPHPのバージョンで良いかも。)
ToolmakerSteve

19

さて、主な違いは、null値に対応する配列キーにisset()は戻りませんtrueが、null値には戻りますarray_key_exists()

小さなベンチマークを実行すると、isset()より高速ですが、完全に正確であるとは限りません。


1
より正確な「(isset($ array [$ i])|| $ array [$ i] === null)」でベンチマークを再度実行できますか?
トマラック2009年

ああ、そして2つのバリアントが示すパフォーマンスの違いの程度を示す指標を投稿しますか?ありがとう!
トマラック2009年

1
@Tomalak、私はあなたが提案した例を実行しました、そしてそれはarray_key_exists()がisset()よりも|| オペレーター。codepad.org/5qyvS93x
アレックス

1
死んでから...でも、ベンチマークを再実行し、微調整を行ったので、2番目のforループは、独自のカウンターを初期化し、結果の配列をクリアする必要があります。「isset || null」の方が高速であることを示しています。codepad.org/Np6oPvgS
KyleWpppd

3
@Tomalakは、 すべてのケースでisset($array[$i]) || $array[$i] === null返さtrueれるため、意味がありません。isset($array[$i]) || $array[$i] === null入力に関係なくfalseになることはありません 。
Pacerier 2015年

10

真ん中の方法が見つからなかったので、この質問に2セントを足したいと思いました。

すでに述べたisset()ように、キーの値を評価するのでfalse、その値がnullどこにあるかを返すのは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 array_key_isset($k, $a){
    return isset($a[$k]) || array_key_exists($k, $a);
}

すでに見たとおり、isset()最も速い方法ですが、値がfalseの場合はfalseを返すことがありますnull。これは望ましくない結果をもたらす可能性があり、そのarray_key_exists()場合は通常使用する必要があります。

しかし、中道があり、それはを使用していisset() || array_key_exists()ます。このコードは通常、より高速な関数を使用してisset()おり isset() falseを返した場合のみarray_key_exists()検証に使用します。上記の表に示されているように、を呼び出すのと同じくらい高速isset()です。

はい、それを書くことは少し多く、関数でそれをラップすることは遅いですがずっと簡単です。パフォーマンスのためにこれが必要な場合は、ビッグデータのチェックなどを行って完全に書き出します。それ以外の場合は、1回の使用で機能のarray_key_isset()ごくわずかなオーバーヘッドは無視できます。


7

Php 7では、Null Coalescing Operatorを使用する可能性があります。

null結合演算子(??)は、isset()と組み合わせて三項を使用する必要がある一般的なケースの構文糖として追加されました。存在し、NULLでない場合は、最初のオペランドを返します。それ以外の場合は、2番目のオペランドを返します。

したがって、値がnullの場合、またはキーが存在しない場合に、デフォルト値を割り当てることができます。

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

6

あなたが読むphp.netとの違いがあります:

isset()は、NULL値に対応する配列キーに対してTRUEを返しませんが、array_key_exists()は返します。

非常に非公式なテストはarray_key_exists()、約2.5倍遅いことを示していますisset()


3

組み合わせisset()is_null()などの他の機能に対して最高のパフォーマンスを与える:array_key_exists()isset()isset()+ array_key_exists()is_null()isset()+ is_null()、ここでの唯一の問題は、キーが存在しない場合、関数は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>";
?>

クレジットhttp : //www.zomeoff.com/php-fast-way-to-determine-a-key-elements-existance-in-an-array/


1

「速く」について:試してみてください(私のお金はかかっていますがarray_key_exists()、今は試すことができません)。

「意図の明確化」について: array_key_exists()


3
isset()は、nullの動作を気にしない場合、実際には大幅に高速化されます(randombenchmarks.com/?p=29を参照)。
Matt Kantor、

0

明らかに、2番目の例は意図がより明確であり、それについては疑問の余地はありません。#1の例を理解するには、PHPの変数初期化の特異性に精通している必要があります。それから、null値の場合とは機能が異なることがわかります。

どちらが速いか-私は推測するつもりはありません-あなたのPHPバージョンでタイトなループで数十万回実行すると、次のことがわかります:)


-2

isset($array[$i]) || $array[$i] === nullキーが存在しない場合でも、コードはすべてtrueを返します(未定義のインデックス通知が生成されます)。最高のパフォーマンスを得るためには、if (isset($array[$key]) || array_key_exists($key,$array)){doWhatIWant();}


1
唯一の時間$array[$i] === null..私は、配列に$が存在すると、NULL値を持っているときに実行されますがある
ニクラス・ラーソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.