什么是更快更好地确定PHP中是否存在数组键?

时间:2009-03-31 06:17:31

标签: php performance

考虑这两个例子......

$key = 'jim';

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

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

我很想知道其中任何一个是否更好。我一直使用第一个,但看到很多人在这个网站上使用第二个例子。

那么哪个更好?快点?更明确的意图?

11 个答案:

答案 0 :(得分:204)

isset()速度更快,但与array_key_exists()不一样。

array_key_exists()纯粹检查密钥是否存在,即使值为NULL

尽管 如果密钥存在且值为isset(),则false将返回NULL

答案 1 :(得分:28)

如果您对我最近做过的一些测试感兴趣:

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%

答案 2 :(得分:18)

嗯,主要区别在于isset()对于与空值对应的数组键不会返回true,而array_key_exists()则会返回isset()

运行small benchmark表示{{1}}速度更快,但可能不完全准确。

答案 3 :(得分:8)

我想在这个问题上增加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()是最快的方法,但如果值为null,则可以返回false。这可能会产生不必要的结果,如果是这种情况,通常应该使用array_key_exists()

然而,有一个中间路径,即使用isset() || array_key_exists()。此代码通常使用更快的函数isset(),如果 isset()返回false ,则使用array_key_exists()进行验证。如上表所示,它与明确调用isset()一样快。

是的,在函数中编写和包装它的速度要慢一点但要容易得多。如果你需要这个来提高性能,检查大数据等就把它全部写出来,否则如果它的1次使用,那么函数array_key_isset()中的非常小的开销可以忽略不计。

答案 4 :(得分:6)

php.net有所不同,您会看到:

  

对于数组,isset()不返回TRUE   对应于NULL值的键,   而array_key_exists()可以。

非正式测试显示array_key_exists()isset()

慢约2.5倍

答案 5 :(得分:2)

结合isset()is_null()可以提供与其他功能相比的最佳效果,例如:array_key_exists()isset()isset() + array_key_exists(),{{ 1}},is_null() + isset(),这里唯一的问题是,如果密钥不存在,函数将不仅返回false,而且即使密钥存在且具有空值。

基准脚本:

is_null()

信用http://www.zomeoff.com/php-fast-way-to-determine-a-key-elements-existance-in-an-array/

答案 6 :(得分:1)

关于“更快”:尝试一下(我的钱在array_key_exists(),但我现在不能尝试)。

至于“意图更明确”:array_key_exists()

答案 7 :(得分:0)

显然,第二个例子在意图上更清晰,毫无疑问。要弄清楚#1的例子,你需要熟悉PHP的变量初始化特性 - 然后你会发现它对于空值的功能不同,等等。

至于哪个更快 - 我不打算推​​测 - 在你的PHP版本上以紧密循环运行几十万次你会发现:)

答案 8 :(得分:0)

Php 7可以使用Null Coalescing Operator

  

对于需要将三元数与isset()结合使用的常见情况,将空合并运算符(??)添加为语法糖。如果它存在且不为NULL,则返回其第一个操作数;否则返回第一个操作数。否则,它将返回其第二个操作数。

因此,现在您可以分配一个默认值,以防该值为null或该键不存在:

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

答案 9 :(得分:-1)

我想补充一点,您还可以使用 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]);
});

答案 10 :(得分:-2)

您的代码isset($array[$i]) || $array[$i] === null将在每种情况下都返回true,即使密钥不存在(并产生未定义的索引通知)。为了获得最佳效果,您需要的是if (isset($array[$key]) || array_key_exists($key,$array)){doWhatIWant();}