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?