O que é mais rápido e melhor para determinar se existe uma chave de matriz no PHP?


157

Considere estes 2 exemplos ...

$key = 'jim';

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

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

Estou interessado em saber se um deles é melhor. Eu sempre usei o primeiro, mas já vi muitas pessoas usarem o segundo exemplo neste site.

Então, qual é o melhor? Mais rápido? Intenção mais clara?


Eu não corri nenhum benchmark, não. Devo ter antes de perguntar?
— 315 de alex

4
issetnunca se comportará exatamente como array_key_existsno exemplo de código que supostamente o faz se comportar de forma idêntica emite um aviso se a chave não existir.
— deceze

Que tal in_array? maettig.com/1397246220
— DanMan

1
@ DanMan, in_arrayé O(n)porque verifica os valores e não as chaves. Eles quase sempre serão mais lentos, a menos que o seu nseja extremamente pequeno.
— Pacerier 8/03/15

Por que não $array[$key] === null?
— Pacerier 2/17/17

Respostas:


237

isset()é mais rápido, mas não é o mesmo que array_key_exists().

array_key_exists()puramente verifica se a chave existe, mesmo que o valor seja NULL.

Considerando isset()que retornará falsese a chave existir e o valor for NULL.


5
Você tem recursos específicos alegando que o isset é mais rápido?
— Francesco Pasa

@Francesco Pasa Basta pensar um pouco. issetnão é uma função de pesquisa de matriz, apenas verifica a presença de uma variável na tabela de símbolos e não itera sobre a matriz. array_key_existspor outro lado, iterará / procurará as chaves na primeira dimensão da matriz especificada.
— Rain

@Rain Tenho certeza de array_key_exists()que apenas verificará se a chave está na matriz, o que significa que ela não fará uma pesquisa, pois é uma tabela de hash.
— Francesco Pasa

@FrancescoPasa Bem, "procurar as chaves" é o que a documentação do PHP diz. Fora isso, não sei dizer se "pesquisar" para eles significa algo completamente diferente do que significa para mim.
— Chuva

32

Se você estiver interessado em alguns testes que fiz recentemente:

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

Resumo:

| 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%

IMPORTANTE: o tempo do arrayKeyExists foi descoberto como muito errado - estava verificando o valor e não a chave - siga esse link para o tempo revisado no 7.1, que é muito melhor. (Também seria melhor em versões anteriores do PHP, se Populus refiz o teste.)
— ToolmakerSteve

19

Bem, a principal diferença é que isset()não retornará truechaves de matriz que correspondam a um valor nulo, enquanto array_key_exists()isso ocorre.

A execução de um pequeno benchmark mostra que isset()é mais rápido, mas pode não ser totalmente preciso.


1
Você pode executar o benchmark novamente com o mais correto "(isset ($ array [$ i]) || $ array [$ i] === null)"?
— Tomalak

Ah, e você indicaria quanta diferença de desempenho as duas variantes mostram? Obrigado!
— Tomalak

1
@Tomalak, executei o exemplo que você sugeriu e afirma que array_key_exists () é mais rápido que isset () com o || operador. #
— alex

1
Acima dos mortos ... mas também refiz o benchmark e fiz um ajuste para que o segundo loop for inicialize seu próprio contador e limpe a matriz de resultados. Ele mostra "isset || nulo" sendo mais rápido. codepad.org/Np6oPvgS
— KyleWpppd

3
@Tomalak, isset($array[$i]) || $array[$i] === nullnão faz sentido, pois retornará truepara todos os casos. Você nunca será falso, isset($array[$i]) || $array[$i] === nullindependentemente das entradas.
— Pacerier 8/03/15

10

Eu queria adicionar meus 2 centavos nessa questão, pois estava faltando uma saída intermediária.

Como já foi dito isset(), avaliará o valor da chave, para que ele retorne falsese esse valor estiver nullonde array_key_exists()apenas verificará se a chave existe na matriz.


Eu executei uma referência simples usando o PHP 7, os resultados mostrados são o tempo que levou para concluir a iteração:

$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

Adicionei os resultados dessa função personalizada a este benchmark para concluir:

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

Como visto e já dito, isset()é o método mais rápido, mas pode retornar falso se o valor for null. Isso pode dar resultados indesejados e, geralmente, deve- array_key_exists()se usar se for esse o caso.

No entanto, existe uma saída intermediária e isso está sendo usado isset() || array_key_exists(). Esse código geralmente usa a função mais rápida isset()e, se isset() retornar falso somente, use array_key_exists()para validar. Mostrado na tabela acima, é tão rápido quanto chamar claramente isset().

Sim, é um pouco mais para escrever e agrupá-lo em uma função é mais lento, mas muito mais fácil. Se você precisar disso para obter desempenho, verifique os big data, etc, escreva-os na íntegra, caso contrário, se o seu uso único for muito pequeno, a sobrecarga na função array_key_isset()será insignificante.


7

Com o Php 7, é possível usar o Operador de coalescência nulo .

O operador coalescente nulo (??) foi adicionado como açúcar sintático para o caso comum de precisar usar um ternário em conjunto com isset (). Retorna seu primeiro operando se existir e não for NULL; caso contrário, ele retornará seu segundo operando.

Portanto, agora você pode atribuir um valor padrão caso o valor seja nulo ou se a chave não existir:

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

6

existe uma diferença do php.net que você lerá:

isset () não retorna TRUE para chaves de matriz que correspondem a um valor NULL, enquanto array_key_exists () sim.

Um teste muito informal mostra array_key_exists()ser cerca de 2,5 vezes mais lento queisset()


3

Combinando isset()e is_null()dar o melhor desempenho em relação a outras funções como: array_key_exists(), isset(), isset()+ array_key_exists(), is_null(), isset()+ is_null(), a única questão aqui é a função não só irá retornar false se a chave não existir, mas até mesmo a exist chave e tem um valor nulo.

Script de benchmark:

<?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>";
?>

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


1

Quanto a "mais rápido": experimente (meu dinheiro está ativo array_key_exists(), mas não posso fazê-lo agora).

Quanto a "mais claro na intenção": array_key_exists()


3
O isset () é realmente significativamente mais rápido se você não se importa com o comportamento nulo (consulte randombenchmarks.com/?p=29 ).
— 31415 Matt Kantor

0

Obviamente, o segundo exemplo é mais claro na intenção, não há dúvida sobre isso. Para descobrir o que o exemplo nº 1 faz, você precisa estar familiarizado com as idiossincrasias de inicialização de variáveis ​​do PHP - e então descobrirá que ele funciona de maneira diferente para valores nulos, e assim por diante.

Quanto ao que é mais rápido - não pretendo especular - corra em um loop apertado algumas centenas de milhares de vezes na sua versão PHP e você descobrirá :)


-2

Seu código isset($array[$i]) || $array[$i] === nullretornará verdadeiro em todos os casos, mesmo que a chave não exista (e produza um aviso de índice indefinido). Para o melhor desempenho, o que você deseja éif (isset($array[$key]) || array_key_exists($key,$array)){doWhatIWant();}


1
A única vez que $array[$i] === nullserá executado é quando $ i existe na matriz e ter o valor NULL ..
— Niclas Larsson
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.