I attached a better patch: no eval and a more standard "inline". Christophe Grand a écrit : > I'm sure there's something wrong with my patch (the "eval" smell) and > the fact that I'm assoc-ing a closure in the metadat map. > I'll rework it if you agree with the idea of this patch > > Christophe Grand a écrit : > >> Rich Hickey a écrit : >> >> >>> On May 13, 9:57 am, Christophe Grand <christo...@cgrand.net> wrote: >>> >>> >>> >>>> Mark Reid a écrit : >>>> >>>> >>>> >>>> >>>>> In particular, it seems converting `(+ 1 2 3)` to `(+ 1 (+ >>>>> 2 3))` can speed things up. >>>>> >>>>> >>>>> >>>> Rich, would you accept a patch to make all arities inlinable for basic >>>> math ops? >>>> >>>> >>>> >>>> >>> What does the patch do? >>> >>> >> Here is the patch, it breaks tests in contrib for (-) and (/) since both >> forms now throw an exception at compile-time. >> >> >> > > >
-- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 2f594af..41f79e1 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -546,45 +546,43 @@ (reduce conj () coll)) ;;math stuff -(defn + +(defmacro + #^{:private true} def-left-op + ([op docstring unary binary] `(def-left-op ~op ~docstring false nil ~unary ~binary)) + ([op docstring zero unary binary] `(def-left-op ~op ~docstring true ~zero ~unary ~binary)) + ([op docstring has-zero? zero unary binary] + (let [inlines (list + `([x#] (concat '~unary [x#])) + `([x# y#] (concat '~binary [x# y#])) + `([x# y# & more#] (reduce (fn [& xy#] (concat '~binary xy#)) (list* x# y# more#)))) + inlines (if has-zero? (cons `([] ~zero) inlines) inlines) + arities (list + `([x#] (~...@unary x#)) + `([x# y#] (~...@binary x# y#)) + `([x# y# & more#] (reduce ~op (~op x# y#) more#))) + arities (if has-zero? (cons `([] ~zero) arities) arities)] + `(defn ~op + ~docstring + {:inline (fn ~...@inlines)} + ~...@arities)))) + +(def-left-op + "Returns the sum of nums. (+) returns 0." - {:inline (fn [x y] `(. clojure.lang.Numbers (add ~x ~y))) - :inline-arities #{2}} - ([] 0) - ([x] (cast Number x)) - ([x y] (. clojure.lang.Numbers (add x y))) - ([x y & more] - (reduce + (+ x y) more))) + 0 (cast Number) (clojure.lang.Numbers/add)) -(defn * +(def-left-op * "Returns the product of nums. (*) returns 1." - {:inline (fn [x y] `(. clojure.lang.Numbers (multiply ~x ~y))) - :inline-arities #{2}} - ([] 1) - ([x] (cast Number x)) - ([x y] (. clojure.lang.Numbers (multiply x y))) - ([x y & more] - (reduce * (* x y) more))) + 1 (cast Number) (clojure.lang.Numbers/multiply)) -(defn / +(def-left-op / "If no denominators are supplied, returns 1/numerator, else returns numerator divided by all of the denominators." - {:inline (fn [x y] `(. clojure.lang.Numbers (divide ~x ~y))) - :inline-arities #{2}} - ([x] (/ 1 x)) - ([x y] (. clojure.lang.Numbers (divide x y))) - ([x y & more] - (reduce / (/ x y) more))) + (/ 1) (clojure.lang.Numbers/divide)) -(defn - +(def-left-op - "If no ys are supplied, returns the negation of x, else subtracts the ys from x and returns the result." - {:inline (fn [& args] `(. clojure.lang.Numbers (minus ~...@args))) - :inline-arities #{1 2}} - ([x] (. clojure.lang.Numbers (minus x))) - ([x y] (. clojure.lang.Numbers (minus x y))) - ([x y & more] - (reduce - (- x y) more))) + (clojure.lang.Numbers/minus) (clojure.lang.Numbers/minus)) (defn < "Returns non-nil if nums are in monotonically increasing order,