What is the performance impact of Scala implicit type conversions?

Viewed 3758

In Scala, is there a significant CPU or memory impact to using implicit type conversions to augment a class's functionality vs. other possible implementation choices?

For example, consider a silly String manipulation function. This implementation uses string concatenation:

object Funky {
  def main(args: Array[String]) {
    args foreach(arg => println("Funky " + arg))
  }
}

This implementation hides the concatenation behind a member method by using an implicit type conversion:

class FunkyString(str: String) {
  def funkify() = "Funky " + str
}

object ImplicitFunky {
  implicit def asFunkyString(str: String) = new FunkyString(str)

  def main(args: Array[String]) {
    args foreach(arg => println(arg.funkify()))
  }
}

Both do the same thing:

scala> Funky.main(Array("Cold Medina", "Town", "Drummer"))        
Funky Cold Medina
Funky Town
Funky Drummer

scala> ImplicitFunky.main(Array("Cold Medina", "Town", "Drummer"))
Funky Cold Medina
Funky Town
Funky Drummer

Is there any performance difference? A few specific considerations:

Does Scala inline the implicit calls to the asFunkyString method?

Does Scala actually create a new wrapper FunkyString object for each arg, or can it optimize away the extra object allocations?

Suppose FunkyString had 3 different methods (funkify1, funkify2, and funkify3), and the body of foreach called each one in succession:

println(arg.funkify1())
println(arg.funkify2())
println(arg.funkify3())

Would Scala repeat the conversion 3 times, or would it optimize away the redundant conversions and just do it once for each loop iteration?

Suppose instead that I explicitly capture the conversion in another variable, like this:

val fs = asFunkyString(arg)
println(fs.funkify1())
println(fs.funkify2())
println(fs.funkify3())

Does that change the situation?

In practical terms, is broad usage of implicit conversions a potential performance issue, or is it typically harmless?

2 Answers
Related