2010-06-16 14 views
6

Jaki jest hit wydajności korzystania z wielu metod? Jeśli mam 2 funkcje o tej samej nazwie i tyle samo argumentów, które różnią się tylko typem (lista vs. int), czy mój występ będzie bardzo cierpieć?Multimethods performance

Innymi słowy, lepiej nazwać moją funkcję dodawania wektorów: "dodaj-wektor" lub pozostawić jako "dodaj" lub ewentualnie "+"?

(Dla uproszczenia zignorujmy problemy, które mogłem zmienić definiując wbudowane funkcje, takie jak "+").

+0

chciałbym odpowiedzieć zamiast komentarza, ale ponieważ nie odnoszą się do Clojure w specyficzny, multimethods nie powinien ponosić żadnej dodatkowej kary niż normalnych wyszukiwań. Oznacza to, że jedną z implementacji jest modyfikowanie nazw, kodujących je za pomocą typów argumentów, a następnie nie powinno być żadnego narzutu. Jednak strategia wdrażania Clojure jest mi nieznana, ale jeśli użyje powyższego mechanizmu, nie będzie dodatkowego obciążenia. – jer

+0

Tak, ponieważ clojure jest dynamicznym językiem, nie sądzę, żeby to było to samo. Również clojure używa funkcji wysyłki, która generuje klucze, które są stosowane do listy dostępnych funkcji. –

+0

Możesz zajrzeć do 'clojure.contrib.generic' i' clojure.contrib.generic. * '(" C.c.generic.arithmetic "będzie prawdopodobnie najbardziej interesujące dla ciebie). –

Odpowiedz

9

Występuje koszt wykonania wielu metod, ale jeśli nie jest to absolutnie konieczne, powinieneś z nich korzystać, jeśli są one najlepszą abstrakcją.

To powiedziawszy, Clojure 1.2, protocols, zapewniają natywną alternatywę dla wielu metod w niektórych przypadkach użycia i są szczególnie odpowiednie w przypadkach, w których wcześniej można było stosować metodę wielotorową z wysyłką opartą na typie.

+0

Doskonale, myślę, że właśnie tego szukam. Protokoły powinny pozwolić mi na "przesłonięcie" funkcji + dla moich klas wektorowych. –

1

Ponieważ Clojure może wykorzystywać dowolne funkcje wysyłki, dodatkowym kosztem multimetra jest koszt funkcji wysyłki + wyszukiwanie mapy.

Albo jak cemerick umieścić go:

(defmulti can-your-dispatch-do-that? 
    (fn [& _] 
    (if (= (phase-of-moon) :full) 
     :do-this 
     :do-that)))