Esta pergunta é apenas para mim, pois sempre gosto de escrever código otimizado que pode ser executado também em servidores lentos e baratos (ou servidores com MUITO tráfego)
Olhei em volta e não consegui encontrar uma resposta. Eu queria saber o que é mais rápido entre esses dois exemplos, tendo em mente que as chaves do array no meu caso não são importantes (pseudo-código naturalmente):
<?php
$a = array();
while($new_val = 'get over 100k email addresses already lowercased'){
if(!in_array($new_val, $a){
$a[] = $new_val;
//do other stuff
}
}
?>
<?php
$a = array();
while($new_val = 'get over 100k email addresses already lowercased'){
if(!isset($a[$new_val]){
$a[$new_val] = true;
//do other stuff
}
}
?>
Como o ponto da questão não é a colisão array, eu gostaria de acrescentar que, se você tem medo de colidir inserções para $a[$new_value]
, você pode usar $a[md5($new_value)]
. ele ainda pode causar colisões, mas impediria um possível ataque DoS ao ler um arquivo fornecido pelo usuário ( http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html )
php
performance
micro-optimization
Fabrizio
fonte
fonte
Respostas:
As respostas até agora são precisas. Usar
isset
neste caso é mais rápido porquein_array
deve verificar todos os valores até encontrar uma correspondência.in_array
função integrada.Isso pode ser demonstrado usando uma matriz com valores (10.000 no teste abaixo), forçando
in_array
a fazer mais pesquisas.Isso se baseia no benchmark de Jason, preenchendo alguns valores aleatórios e, ocasionalmente, encontrando um valor que existe na matriz. Tudo aleatório, então tome cuidado, pois os tempos irão flutuar.
fonte
isset()
é mais rápido.Embora deva ser óbvio,
isset()
testa apenas um único valor. Visto quein_array()
irá iterar em todo o array, testando o valor de cada elemento.O benchmarking aproximado é bastante fácil de usar
microtime()
.Resultados:
Nota: Os resultados foram semelhantes, independentemente se existiam ou não.
Código:
Recursos adicionais
Eu o encorajo a olhar também para:
fonte
microtime()
ou outras ferramentas. Incrivelmente valioso.in_array
função em comparação com o uso doisset
embutido. Isso seria melhor com uma matriz contendo um monte de chaves aleatórias e ocasionalmente procurando por uma chave / valor existente.while
eforeach
que em cada atualização que eu estava ficando diferentes "vencedores". sempre depende de muitas variáveis de servidor, e o melhor é iterar um número muito grande de vezes em momentos diferentes e conseguir aquele que ganha com mais frequência, ou apenas saber o que está acontecendo em segundo plano e saber que será o vencedor final não importa o queisset()
, o que o faz pensar que transmiti-la a um array maior a tornaria mais rápida ?O uso
isset()
aproveita a pesquisa mais rápida porque usa uma tabela hash , evitando a necessidade deO(n)
pesquisas.A chave é hash primeiro usando a função djb hash para determinar o intervalo de chaves com hash semelhantes em
O(1)
. O balde é então pesquisado iterativamente até que a chave exata seja encontrada emO(n)
.Excluindo quaisquer colisões de hash intencionais , essa abordagem produz um desempenho muito melhor do que
in_array()
.Observe que, ao usar
isset()
da maneira que você mostrou, passar os valores finais para outra função requer o usoarray_keys()
para criar um novo array. Um compromisso de memória pode ser feito armazenando os dados nas chaves e valores.Atualizar
Uma boa maneira de ver como suas decisões de design de código afetam o desempenho do tempo de execução, você pode verificar a versão compilada de seu script:
echo isset($arr[123])
echo in_array(123, $arr)
Não apenas
in_array()
usa umaO(n)
pesquisa relativamente ineficiente , mas também precisa ser chamada como uma função (DO_FCALL
), enquantoisset()
usa um único opcode (ZEND_ISSET_ISEMPTY_DIM_OBJ
) para isso.fonte
O segundo seria mais rápido, pois está procurando apenas por aquela chave de array específica e não precisa iterar em todo o array até que seja encontrado (vai olhar para cada elemento do array se não for encontrado)
fonte
isset()
se ele não fosse encontrado?