Cette question est simplement pour moi car j'aime toujours écrire du code optimisé qui peut également fonctionner sur des serveurs lents bon marché (ou des serveurs avec BEAUCOUP de trafic)
J'ai regardé autour de moi et je n'ai pas pu trouver de réponse. Je me demandais ce qui est le plus rapide entre ces deux exemples en gardant à l'esprit que les clés du tableau dans mon cas ne sont pas importantes (pseudo-code naturellement):
<?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
}
}
?>
Comme le point de la question n'est pas la collision de tableaux, je voudrais ajouter que si vous avez peur de heurter des insertions pour $a[$new_value]
, vous pouvez utiliser $a[md5($new_value)]
. cela peut toujours provoquer des collisions, mais enlèverait une éventuelle attaque DoS lors de la lecture d'un fichier fourni par l'utilisateur ( http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html )
la source
Réponses:
Les réponses à ce jour sont justes. L'utilisation
isset
dans ce cas est plus rapide carin_array
doit vérifier chaque valeur jusqu'à ce qu'il trouve une correspondance.in_array
fonction intégrée.Celles-ci peuvent être démontrées en utilisant un tableau avec des valeurs (10 000 dans le test ci-dessous), ce
in_array
qui oblige à faire plus de recherche.Cela s'appuie sur le benchmark de Jason en remplissant des valeurs aléatoires et en trouvant occasionnellement une valeur qui existe dans le tableau. Tous aléatoires, alors méfiez-vous que les temps vont fluctuer.
la source
isset()
est plus rapide.Bien que cela devrait être évident,
isset()
ne teste qu'une seule valeur. Alors quein_array()
va itérer sur tout le tableau, en testant la valeur de chaque élément.Une analyse comparative approximative est assez facile à utiliser
microtime()
.Résultats:
Remarque: les résultats étaient similaires, qu'ils existent ou non.
Code:
Ressources supplémentaires
Je vous encourage à regarder également:
la source
microtime()
ou d'autres outils. Incroyablement précieux.in_array
fonction par rapport à l'utilisation de la fonctionisset
intégrée. Ce serait mieux avec un tableau contenant un tas de clés aléatoires et recherchant occasionnellement une clé / valeur existante.while
etforeach
qu'à chaque rafraichissement, j'obtenais différents "gagnants". cela dépend toujours d'un trop grand nombre de variables de serveur, et le mieux est d'itérer un très grand nombre de fois à des moments différents et d'obtenir celui qui gagne le plus souvent, ou simplement de savoir ce qui se passe en arrière-plan et de savoir que ce sera le vainqueur final quoi qu'ilisset()
, qu'est-ce qui vous fait penser que passer un tableau plus grand le rendrait plus rapide ?L'utilisation
isset()
tire parti d'une recherche plus rapide car elle utilise une table de hachage , évitant ainsi le besoin deO(n)
recherches.La clé est d'abord hachée à l'aide de la fonction de hachage djb pour déterminer le compartiment de clés hachées de manière similaire dans
O(1)
. Le compartiment est ensuite recherché de manière itérative jusqu'à ce que la clé exacte soit trouvée dansO(n)
.À moins de collisions de hachage intentionnelles , cette approche donne de bien meilleures performances que
in_array()
.Notez que lors de l'utilisation
isset()
de la manière que vous avez montrée, passer les valeurs finales à une autre fonction nécessite d'utiliserarray_keys()
pour créer un nouveau tableau. Un compromis de mémoire peut être fait en stockant les données à la fois dans les clés et les valeurs.Mettre à jour
Un bon moyen de voir comment vos décisions de conception de code affectent les performances d'exécution, vous pouvez consulter la version compilée de votre script:
echo isset($arr[123])
echo in_array(123, $arr)
Non seulement
in_array()
utilise uneO(n)
recherche relativement inefficace , mais elle doit également être appelée en tant que fonction (DO_FCALL
) alors qu'elleisset()
utilise un seul opcode (ZEND_ISSET_ISEMPTY_DIM_OBJ
) pour cela.la source
Le second serait plus rapide, car il ne recherche que cette clé de tableau spécifique et n'a pas besoin d'itérer sur tout le tableau jusqu'à ce qu'il soit trouvé (examinera chaque élément du tableau s'il n'est pas trouvé)
la source
isset()
s'il n'est pas trouvé?