A Scala example using method calls:
#Inc.scala
object Inc {
   def main(args: Array[String]):Unit =
   {
       var i:Int=0

       for(j <- (1 to 1000000000)) // Scala!, Y U No Project Coin? ;)
       {
           i = inc(i)
       }

       println(i);
   }

   def inc(i:Int):Int=i+1
}
The same code using tail recursion (@tailrec)
#TailRec.scala
import scala.annotation.tailrec

object TailRec {
   def main(args: Array[String]):Unit =
   {
       var i = inc(0, 1000000000)
   
       println(i);
   }

   @tailrec
   def inc(i:Int, iter:Int):
       Int=if (iter>0)
           inc(i+1, iter-1)
       else i
}
Compile them both using scalac:
scalac Inc.scala
scalac TailRec.scala
Time the runs (obviously would be better with JMH!):
time ./bin/scala Inc
1000000000

real   0m4.461s
user   0m4.220s
sys    0m0.184s

time ./bin/scala TailRec
1000000000

real   0m1.558s
user   0m1.540s
sys    0m0.140s
Hmmm, looks like inlining that method took a while to kick in!
How about with no inlining?
time ./bin/scala Inc -J-XX:-Inline
1000000000

real   0m28.890s
user   0m28.790s
sys    0m0.120s

time ./bin/scala TailRec -J-XX:-Inline
1000000000

real   0m1.534s
user   0m1.532s
sys    0m0.096s
Ouch! Remember kids, inlining is your friend. Keep those methods small ;)
Here's the bytecode for the inc() method:
#Inc
 public int inc(int);
   flags: ACC_PUBLIC
   Code:
     stack=2, locals=2, args_size=2
        0: iload_1      
        1: iconst_1      
        2: iadd          
        3: ireturn      
     LocalVariableTable:
       Start  Length  Slot  Name   Signature
              0       4     0  this   LInc$;
              0       4     1     i   I
     LineNumberTable:
       line 14: 0
And here it is for the tailrec version
#TailRec
 public int inc(int, int);
   flags: ACC_PUBLIC
   Code:
     stack=3, locals=3, args_size=3
        0: iload_2      
        1: iconst_0      
        2: if_icmple     16
        5: iload_1      
        6: iconst_1      
        7: iadd          
        8: iload_2      
        9: iconst_1      
       10: isub          
       11: istore_2      
       12: istore_1      
       13: goto          0
       16: iload_1      
       17: ireturn      
     LocalVariableTable:
       Start  Length  Slot  Name   Signature
              0      18     0  this   LTailRec$;
              0      18     1     i   I
              0      18     2  iter   I
     LineNumberTable:
       line 13: 0
       line 14: 5
       line 15: 16
       line 12: 17
     StackMapTable: number_of_entries = 2
          frame_type = 0 /* same */
          frame_type = 15 /* same */
JITWatch inspection of Inc with inlining:
JITWatch inspection of Scala inlined method
JITWatch inspection of Inc without inlining:
JITWatch inspection of Scala method not inlined
With thanks to Ignasi Marimon-Clos (@ignasi35) for the Scala help and to Jean-Philippe Bempel (@jpbempel) for pointing out -XX:-Inline :)