Non your examples will get any faster because if you use recur
you already tell the compiler that you have a tail recursive function and this allows the compiler to generate byte code that uses goto
(like a normal imperative loop)
There is off course some benefits if the JVM gets tail call optimization.
You wont have to use recur anymore (if you don't want to) so you can write a function like this (a tail recursive function)
(defn testfn [n] (when (not= 1000 n) (testfn n)))
Nowdays the JVM is not able to detect the tail recursion. With the addition of tail call optimization the JVM able to see the function above just as if you had written this (and therefore get imperative loop speed):
(defn testfn [n] (when (not= 1000 n) (recur n)))
So that not that great of an improvement but there is another case where the tail call optimization is really great.
If you have functions that call each other (sometimes even more then two) and the do not need to hold on the the stack (are tail recursive) the JVM can optimize them. This is not possible now because you can not tell recur
to jump to some other function. Here is an example.
(defn even [n] (if (zero? n) true (odd? (dec n)))
(defn odd [n] (if (zero? n) false (even (dec n)))
If you try this with a big number know you will blow the stack but with tail call optimization you won't.
I have on little addition left. There is a function called trampoline
that allow you do this already (with a little change in programming style and some overhead) Instead of explaining trampoline
I will refer you to a blog that does exactly that:
http://pramode.net/clojure/2010/05/08/clojure-trampoline/