La Performance de jQuery.grep vs Tableau.filtre
Dans un question il a été discuté sur la façon de jQuery et natif JS serait exécuter les uns contre les autres.
Bien que la vanille solution exécute beaucoup plus rapidement car il ne traite pas l'ensemble du tableau, j'ai proposé l'utilisation de Array.filter
qui j'étais assez confiant serait au moins plus vite que $.grep
.
Étonnamment après l'ajout à l'épreuve m'a appris une leçon: Testsuite
Edgecases bien sûr d'avoir un résultat différent.
Toute personne ayant une idée de pourquoi $.grep
est censé être plus de 3 fois plus rapide que la méthode native Arrray.filter
?
Edit: j'ai modifié le test à utiliser le filtre cale de MDN et les résultats sont assez intéressants:
- Chrome: Même MDN cale est plus rapide que la méthode native, jQuery avance
- Firefox: cale un peu plus lente que la méthode native, jQuery avance
et enfin à un tel résultat, je m'attendais à voir dans
- Internet Explorer:
natif méthode est la plus rapide, jQuery, la cale est plus lent (c'est peut-être simplement le résultat de l'IEs plutôt faible JS-moteur...)
Vous devez vous connecter pour publier un commentaire.
Que l'on trouve sur ce blog (qui fait aussi le même genre de tests):
Array.filter
mise en œuvre, c'est juste une solution de repli.Array.filter
est une méthode native mis en œuvre dans le JS moteur (C++).Section 15.4.4.20 de l'ECMAScript 5.1 spec définit
Array.prototype.filter(callbackfn, thisArg)
comme suit:Ce qui en soi est déjà beaucoup de travail, beaucoup de mesures que le moteur ECMAScript besoin pour exécuter.
Puis il poursuit en disant que les suivantes:
Des choses à noter à propos de cet algorithme:
Dans beaucoup de cas, aucune de ces choses sont nécessaires. Ainsi, lors de l'écriture d'un
filter
méthode de votre propre, la plupart du temps vous ne serait même pas pris la peine d'effectuer ces étapes.Chaque ES5.1-conforme moteur JavaScript doit être conforme à celle de l'algorithme, et doit donc effectuer toutes ces étapes chaque fois que vous utilisez
Array#filter
.Il ne faut pas s'étonner que tout écrit sur mesure méthode qui ne réalise qu'une partie de ces étapes sera plus rapide 🙂
Si vous écrivez votre propre
filter
fonction, les chances sont qu'il ne va pas être aussi complexe que l'algorithme ci-dessus. Peut-être que vous ne serez pas la conversion de la matrice à un objet, comme selon le cas d'utilisation, il peut ne pas être nécessaire de filtrer le tableau.IsCallable(callbackfn)
estfalse
, jeter unTypeError
exception.” La cale vérifie cela en utilisanttypeof
, qui diffère de laIsCallable
de l'algorithme dans le spec. Le résultat final est le même, mais c'est un tout autre chemin d'accès au code, potentiellement différente de la performance de coût.J'ai trouvé quelque chose d'intéressant. Comme l'a expliqué MarcoK, $.grep est juste une mise en œuvre simple avec une boucle for. Le filtre est plus lente dans la plupart des cas, de sorte que la mise en œuvre doit être différent. Je crois que j'ai trouvé la réponse:
Le natif de "filtre" est beaucoup plus rapide dans ce cas. Je pense donc qu'il réitère les propriétés plutôt que l'index du tableau.
Maintenant revenons aux "grands" problèmes ;).
Array.prototype.filter
ignore les lacunes dans le tableau et n'invoque la fonction de filtre 11 fois, tandis quegrep
invoque 10001 fois.N'est pas votre script de mal?
Pour
array.filter
vous faites la mesure 1000 fois et de le présenter pour prendre la somme divisée par 1000Pour
JQuery.grep
vous faites de la mesure 1 du temps et de la présenter pour prendre la somme divisée par 1000.Que signifie votre commande grep est en fait 1000 fois plus lent que la valeur que vous utilisez à des fins de comparaison.
Test rapide dans firefox donne:
Test rapide en chrome donne:
Conclusion dans firefox (50.0) est beaucoup plus rapide pour votre chemin de code, et le filtre est d'environ 10 à 15% plus rapide que celui de jquery.grep.
Chrome est très lente pour votre chemin de code, mais grep semble être 50% plus rapide que le tableau.filtre ici en fait de 900% plus lent que firefox exécuter.
TLDR; Grep est plus rapide par un séisme de magnitude... (un indice sur le pourquoi du peuvent être trouvés ici)
Voici le script que j'ai utilisé pour le test:
JS:
HTML: