This is because in the second case, the argument passed is placed in the field. Add a type hint to fix this:
user> (defn tl [^long r] (loop [n 0 t 0] (if (= nr) t (recur (inc n) (+ tn))))) user> (time (tl 10000000)) "Elapsed time: 20.268396 msecs" 49999995000000
UPD:
12). In the first case, you work with java primitives, so itβs so fast. ^Integer will not work here because it is typing a hint for the nested type java.lang.Integer (why it is capitalized). ^long is a hint type exactly for the java long primitive. For function parameters, you can use only ^long and ^double hints of a primitive type ( others are not supported , in addition, you can enter type types for all types of primitive arrays, for example ^floats , ^bytes , etc.).
3) Since the argument passed is boxed, this forces general arithmetic for all operations. In other words, each operation + and inc will create a new object on the heap (in the case of primitives, they will remain on the stack).
UPD 2:
As an alternative to type notation, you can explicitly convert the passed argument to a primitive before the loop:
user> (defn tl [r] (let [r (long r)] (loop [n 0 t 0] (if (= nr) t (recur (inc n) (+ tn)))))) user> (time (tl 10000000)) "Elapsed time: 18.907161 msecs" 49999995000000
source share