En JS, ce qui est plus rapide: Objet de l'opérateur “in” ou de la Matrice indexof?
Je tiens à garder une liste de chaînes de caractères que je ne jamais vérifier la présence d', par exemple:
corporatePlan = [
'canDeAuthorize',
'hasGmailSupport',
'canShareReports',
'canSummonKraken',
'etc'
]
Ainsi, lorsque l'utilisateur tente d'invoquer le kraken, je vais le faire corporatePlan.indexof('canSummonKraken') != -1
pour voir si il peut.
Un collègue suggère qu'il serait plus rapide pour stocker un objet:
"Corporate Plan" = {
'canDeAuthorize' : null,
'hasGmailSupport' : null,
'canShareReports' : null,
'canSummonKraken' : null,
'etc' : null
}
Et il suffit de faire quelque chose comme 'canSummonKraken' in corporatePlan
pour vérifier si le plan contient cette clé. Cela a du sens dans un classique de la CS de sens, puisque bien entendu, 'contient' est la constante de temps sur une carte et linéaire sur un tableau. Est-ce à vérifier à l'encontre de la façon dont les tableaux et les objets sont mis en œuvre sous le capot en JS, si?
Dans notre cas particulier, avec moins de 100 éléments, la vitesse n'a pas beaucoup d'importance. Mais pour un ensemble plus grand, ce qui serait plus rapide sur l'accès?
- N'oubliez pas la virgule après le
null
s dans votre objet littéral. - Bon d'appel fixe.
@Fish
: FWIW, j'ai mis à jour ma réponse à proposer une troisième option qui, je pense, serait assez normal de chemin à faire.- cochez cette référence: jsben.ch/#/Y9jDP
Vous devez vous connecter pour publier un commentaire.
En JavaScript, vous êtes généralement affaire à une grande variété de mises en œuvre (sauf si vous l'utilisez dans un environnement contrôlé comme un serveur où vous choisissez le moteur), et donc, la réponse spécifique des questions de performances ont tendance à être "ça dépend, vérifier sur les moteurs que vous allez utiliser." Ce qui est plus rapide sur une mise en œuvre peut être plus lent sur un autre, etc. http://jsperf.com est pratique pour ce genre de chose.
Cela dit, je m'attends à ce
in
pour être un gagnant clair ici.Array#indexOf
a accéder au tableau d'index dans une recherche, et les indices de tableau sont des propriétés comme toute autre propriété. L'accès à d'index de tableau0
pour voir si c'est la chaîne souhaitée, il faut examiner jusqu'0
tout comme les autres nécessite la recherche de la propriété"canSummonKraken"
(et puis il doit faire une comparaison de chaîne par la suite). (Oui, les indices de tableau sont des propriétés. Les tableaux en JavaScript ne sont pas vraiment des tableaux à tous.) EtindexOf
peut avoir accès à plusieurs de ces propriétés au cours de sa recherche, alors quein
n'aurez qu'à en avoir un. Mais encore une fois, vous aurez besoin de vérifier dans votre cible environemnts pour être sûr, certaines implémentations peuvent optimiser les tableaux qui ont contiguë indice va (mais plus lentes certainement n'avez pas, et bien sûr, si vous êtes inquiet au sujet de la vitesse, vous êtes inquiet au sujet de ce qui est le plus rapide à la plus lente des moteurs, comme IE).Également noter que tous les moteurs JavaScript ont même
Array#indexOf
encore. La plupart le font, mais il y a encore quelques anciens coups de pied autour (je suis à la recherche à vous, Microsoft) qui ne sont pas.Vous avez également la question de savoir si l'utilisation
in
ouhasOwnProperty
. À l'aide dein
a l'avantage que c'est un opérateur, de ne pas l'appel de la fonction; à l'aide dehasOwnProperty
a l'avantage qu'il ne vous regardez à l'objet spécifique de l'instance et non de son prototype (et son prototype, etc.). Sauf si vous avez un très profondément hérité de la hiérarchie (et vous n'avez pas dans votre exemple), je pariein
victoires, mais il est utile de rappeler qu'il ne vérifie pas la hiérarchie.Aussi, n'oubliez pas que
"canSummonKraken" in obj
sera vrai dans l'exemple littéral d'objet vous a montré, parce que l'objet n'en avoir la propriété, même si la valeur de la propriété est null. Vous avez de ne pas avoir la propriété à tous les pour en retourner false. (Au lieu dein
, vous pouvez simplement utiliser le vrai et le faux et le regarder commeobj.canSummonKraken
.)Afin que vos options sont les suivantes:
Votre méthode de tableau:
...je ne le recommande pas.
La
in
méthode:Probablement plus rapide que la
indexOf
, mais j'aimerais le tester. Utile si la liste pourrait être très longue et si vous allez avoir un grand nombre de ces objets, car il exige seulement que le "truthy" propriétés existent à tous. Un objet vide représente un plan où l'utilisateur ne peut pas tout faire, et il est relativement petit.Je note deux choses ici:
in
vérifie le prototype de l'objet, ainsi, si vous avez eu des paramètres commetoString
ouvalueOf
, vous souhaitez obtenir de faux positifs (comme ceux qui sont propriétés près de tous les objets deObject.prototype
). Sur un ES5 est activé sur votre navigateur, vous pouvez éviter ce problème en créant votre objet avec unnull
prototype:var corporatePlan = Object.create(null);
Peut-être parce qu'il vérifie les prototypes, les
in
opérateur est étonnamment lent sur certains moteurs.Ces deux problèmes peuvent être résolus en utilisant
hasOwnProperty
à la place:On pourrait penser à un opérateur d'être plus rapide qu'un appel de méthode, mais il s'avère que c'est pas fiable de la vraie-croix-navigateur.
Les drapeaux de la méthode:
...qui serait assez normal de chemin à faire, probablement plus rapide que
in
, et probablement au moins aussi vite quehasOwnProperty
. (Mais voir mon paragraphe d'ouverture: de Test dans votre environnement. 🙂 )in
n'avons pas à chercher des éléments tels que l'indexation n'.Je l'ai testé: http://jsperf.com/array-indexof-vs-object-s-in-operator/4
Lors de la recherche le premier élément, les deux ont de bons résultats en fonction du navigateur est en cours d'utilisation.
Afin de trouver le dernier élément, le
in
Opérateur est beaucoup plus rapide.Mais ensuite, j'ai utilisé une variante avec l'opérateur typeof, ce qui est beaucoup plus rapide que la fois:
typeof !== 'undefined'
, au lieu de!== undefined
?typeof
retourne une chaîne de caractères n'est pas un objet; vous êtes, en ajoutant une contrainte de là. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...obj['that'] !== undefined
qui est beaucoup plus rapide que la comparaison de chaînes.undefined
n'est pas constante et peut être écrasé. Il est beaucoup plus sûr de vérifier pour"undefined"
.Ici est une référence http://jsperf.com/array-indexof-vs-object-keys.
Dans chrome et firefox, de vérifier la présence d'une clé dans l'objet est 100% plus rapide que l'analyse de la matrice.
Mais si vous prenez le temps d'initialisation en compte, la différence annule, des objets prend de façon de plus de temps pour initialiser que les tableaux.