Есть ли в Scala значительное влияние ЦП или памяти на использование неявных преобразований типов для расширения функциональных возможностей класса по сравнению с другими возможными вариантами реализации?
Например, рассмотрим глупую функцию манипуляции со строками. Эта реализация использует конкатенацию строк:
object Funky {
def main(args: Array[String]) {
args foreach(arg => println("Funky " + arg))
}
}
Эта реализация скрывает конкатенацию за методом-членом, используя неявное преобразование типов:
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()))
}
}
Оба делают одно и то же:
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
Есть ли разница в производительности? Несколько конкретных соображений:
Имеет ли Scala встроенные неявные вызовы метода asFunkyString?
Создает ли Scala новый объект-оболочку FunkyString для каждого аргумента или оптимизирует выделение дополнительных объектов?
Предположим, что FunkyString имеет 3 различных метода (funkify1, funkify2 и funkify3), и тело foreach вызывает каждый из них по очереди:
println(arg.funkify1())
println(arg.funkify2())
println(arg.funkify3())
Будет ли Scala повторять преобразование 3 раза или оптимизировать избыточные преобразования и делать это только один раз для каждой итерации цикла?
Предположим, вместо этого я явно фиксирую преобразование в другую переменную, например так:
val fs = asFunkyString(arg)
println(fs.funkify1())
println(fs.funkify2())
println(fs.funkify3())
Это меняет ситуацию?
С практической точки зрения, является ли широкое использование неявных преобразований потенциальной проблемой производительности или оно обычно безвредно?