Why does this function require more than 10 times to complete the operation?

Can someone explain why time jumps an order of magnitude simply by wrapping it in a function?

user> (time (loop [n 0 t 0] (if (= n 10000000) t (recur (inc n) (+ tn))))) "Elapsed time: 29.312145 msecs" 49999995000000 user> (defn tl [r] (loop [n 0 t 0] (if (= nr) t (recur (inc n) (+ tn))))) #< Var@54dd6004 : #object[user$eval3462$tl__3463 0x7d8ba46 " user$eval3462$tl__3463@7d8ba46 "]> user> (time (tl 10000000)) "Elapsed time: 507.333844 msecs" 49999995000000 

I am curious how a simple iteration can be done much faster. For example, a similar iterative loop in C ++ takes less than 1 ms in release mode or about 20 ms in debug mode on the same system as this Clojure.

+5
source share
1 answer

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 
+9
source

All Articles