3 Réponses :
MultiMethods de Clojure Autoriser le comportement polymorphe d'exécution basé sur des fonctions d'expédition arbitraires. Ceci est très puissant pour construire des hiérarchies et des abstractions ad-hoc, mais vous payez une performance frappée pour une telle flexibilité. Vous voudrez peut-être ré-implémenter votre solution avec un protocole. Utilisez uniquement des multimods lorsque vous avez besoin de flexibilité complète de type d'exécution. P>
J'avais considéré un protocole mais du Documentation Les fonctions résultantes Expédition sur le type de leur premier argument, Et donc doit avoir au moins un argument code> et ce qui est nécessaire est une expédition sur la valeur code> de l'argument.
En général Tout ce qui prendra plus de temps b>. Étant donné que les multimethods offrent une variété de moyens de dépêcher, ils prendront plus de temps que des protocoles que je dois répondre à votre question "Oui, par rapport aux protocoles". p>
En pratique, commencez avec les protocoles et accédez à des multimethodes lorsque vous devez (et cela ressemble à vous en avez besoin). Vous ne pouvez pas rendre l'ordinateur plus rapidement avec le code, mais vous pouvez le faire faire moins b> p>
Je pense que la raison pour laquelle votre implémentation multi-méthodes est plus lente peut également être dû au fait que vous utilisez de la suite sur une séquence paresseuse (fournie par plage) au lieu de la boucle / recurez sur un index d'incrémentation utilisé dans Clojure.core. Essayez de copier la partie de la boucle de la mise en œuvre de Clojure.core / Re-groupes dans votre deuxième défméthod et voyez si cela n'augmente pas la performance. P>
Il est difficile de dire sans voir votre cas de test, mais s'il y a beaucoup de groupes dans le matcheur, vous pouvez dépenser beaucoup plus de temps pour réduire les groupes dans un vecteur que dans l'expédition multi-méthodes. S'il y a peu de groupes cependant, l'expédition multi-méthodes sera une partie plus importante du temps passé. Dans les deux cas, avoir la même mise en œuvre éliminera un facteur contribuant potentiel à la différence de chronométrage et vous aidera à mieux vous sentir pour la surcharge réelle dans l'expédition multi-méthodes. P>
Une autre chose que vous pourriez envisager est la possibilité que le ralentissement soit dû à la réflexion. Essayez de régler * warn-on-réflexion * à vrai et voir s'il se plaint. Peut-être qu'un autre indice de type stratégique peut aider. P>
J'ai utilisé cela pour obtenir les timings: (heure (Count (Map Recours (Cycle [# »[- +]? [0-9] + / ([0-9]) +" # "([ - +]? [0-9] +) / ([0-9]) + "#" [- +]? [0-9] + / [0-9] + "#" Hamster "]) (prendre 200000 (pour [x (plage) y (plage x)] (STR x "/" y)))))))) code>
Vous semblez utiliser MultiMethods comme une sorte de construction de correspondance de modèle ici. C'est vraiment pas i> le but de MultiMethod, qui est (multi) expédition. Pensez-y comme un superset de ce qui est possible dans les langues orientées objet. Pour utiliser des protocoles d'utilisation unique (comme OO Stuff). Pour la correspondance de patterns, utilisez ceci: Github.com/swannodette/match
En outre, le code Clojure.core est la façon dont il s'agit précisément pour la raison de la performance. La plupart des autres implémentations seront plus lentes.