Hi,
I was stepping through a very simply test (not meant to be performant) and
noticed the following:
(ns test.performance.fibonachi)
(defn fib [a]
(if (< a 2)
a
(+ (fib (- a 1)) (fib (- a 2)))))
(fib 45)
Stepping into (if ...) noticed that (< a 2) called into the following Java code:
>From Numbers.java:
static public boolean lt(Object x, Object y){
return ops(x).combine(ops(y)).lt((Number)x, (Number)y);
}
Stepping further into ops(x):
static Ops ops(Object x){
Class xc = x.getClass();
if(xc == Integer.class)
return INTEGER_OPS;
else if(xc == Double.class)
return DOUBLE_OPS;
else if(xc == Float.class)
return FLOAT_OPS;
else if(xc == BigInteger.class)
return BIGINTEGER_OPS;
else if(xc == Long.class)
return LONG_OPS;
else if(xc == Ratio.class)
return RATIO_OPS;
else if(xc == BigDecimal.class)
return BIGDECIMAL_OPS;
else
return INTEGER_OPS;
}
Yow!, if this is very inefficient! If this sort of code is being evaluated
all of the time for arithmetic the performance is going to suffer
substantially. I do a lot of fundamental operations on arrays in my
numerical work at high frequency, so extra overhead will mean that the
algorithm in some factor x slower. (again I recognize this is not an issue for
95% of the applications out there). Is there a special optimisation that
avoids the dispatch? I note that type annotation does not seem to avoid this
(or at least what I understand of annotation).
(defn fib [#^Integer a]
(if (< a 2)
a
(+ (fib (- a 1)) (fib (- a 2)))))
I'm just learning, so I may have overlooked something that mitigates or
otherwise avoids dispatch.
Jonathan
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en