That looks like a bad example to me, since the stuff about map-lookup just confuses the issue.
A more realistic example would be:
(def pi 3.14)
(defn circ [r] (* 2 pi r))
In this case, the body of circumference is compiled into code that dereferences pi at runtime (by calling Var.getRawRoot), each time circumference is called.
(def ^:const pi 3.14)
(defn circ2 [r] (* 2 pi r))
In this case, circ2
is compiled into exactly the same code as if it had been written like this:
(defn circ2 [r] (* 2 3.14 r))
That is, the call to Var.getRawRoot is skipped, which saves a little bit of time. Here is a quick measurement, where circ is the first version above, and circ2 is the second:
user> (time (dotimes [_ 1e5] (circ 1)))
"Elapsed time: 16.864154 msecs"
user> (time (dotimes [_ 1e5] (circ2 1)))
"Elapsed time: 6.854782 msecs"
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…