Scala 中的方法调用反射会导致性能下降吗?
Will method invocation reflection in Scala cause performance degradation?
我有一个方法打算对数据IO做一些简单的统计,如下图。
def ioStatSink[T <: { def length: Int }](): Sink[T, Future[(Long, Long)]] = Sink.fold((0L, 0L))((acc, bytes) => (acc._1 + 1L, acc._2 + bytes.length))
因为我希望它能够处理具有 { def length: Int }
方法的不同数据类型,所以我将其设为通用。
问题是,这个方法调用使用了反射。
由于此方法被调用了数百万次,我不希望它出现性能问题。
我知道 class 使用反射实例化会降低性能,但是这个方法调用怎么样?
(关于该方法的另一个问题是,它无法适应具有{ def length: Long }
方法的类型,有什么解决这个问题的建议吗?)
既然你说你对 typeclass 替代方案感兴趣。
这是一个简单的演示。
import scala.language.higherKinds
trait Sizeable[T] {
def size(t: T): Long
}
object Sizeable {
private final val _IterableOnceSizable: Sizeable[IterableOnce[_]] =
new Sizeable[IterableOnce[_]] {
override final def size(iter: IterableOnce[_]): Long = {
val knownSize = iter.knownSize
if (knownSize == -1) iter.iterator.size.toLong
else knownSize.toLong
}
}
implicit final def CollectionSizeable[C[_], T](implicit ev: C[T] <:< IterableOnce[T]): Sizeable[C[T]] =
_IterableOnceSizable.asInstanceOf[Sizeable[C[T]]]
}
object syntax {
object sizeable {
implicit class SizeableOps[T](private val sizable: T) extends AnyVal {
@inline def size(implicit ev: Sizeable[T]): Long =
ev.size(sizable)
@inline def length(implicit ev: Sizeable[T]): Long =
ev.size(sizable)
}
}
}
import syntax.sizeable._
def ioStatSink[T : Sizeable](): Sink[T, Future[(Long, Long)]] =
Sink.fold((0L, 0L))((acc, bytes) => (acc._1 + 1L, acc._2 + bytes.length))
我有一个方法打算对数据IO做一些简单的统计,如下图。
def ioStatSink[T <: { def length: Int }](): Sink[T, Future[(Long, Long)]] = Sink.fold((0L, 0L))((acc, bytes) => (acc._1 + 1L, acc._2 + bytes.length))
因为我希望它能够处理具有 { def length: Int }
方法的不同数据类型,所以我将其设为通用。
问题是,这个方法调用使用了反射。
由于此方法被调用了数百万次,我不希望它出现性能问题。
我知道 class 使用反射实例化会降低性能,但是这个方法调用怎么样?
(关于该方法的另一个问题是,它无法适应具有{ def length: Long }
方法的类型,有什么解决这个问题的建议吗?)
既然你说你对 typeclass 替代方案感兴趣。
这是一个简单的演示。
import scala.language.higherKinds
trait Sizeable[T] {
def size(t: T): Long
}
object Sizeable {
private final val _IterableOnceSizable: Sizeable[IterableOnce[_]] =
new Sizeable[IterableOnce[_]] {
override final def size(iter: IterableOnce[_]): Long = {
val knownSize = iter.knownSize
if (knownSize == -1) iter.iterator.size.toLong
else knownSize.toLong
}
}
implicit final def CollectionSizeable[C[_], T](implicit ev: C[T] <:< IterableOnce[T]): Sizeable[C[T]] =
_IterableOnceSizable.asInstanceOf[Sizeable[C[T]]]
}
object syntax {
object sizeable {
implicit class SizeableOps[T](private val sizable: T) extends AnyVal {
@inline def size(implicit ev: Sizeable[T]): Long =
ev.size(sizable)
@inline def length(implicit ev: Sizeable[T]): Long =
ev.size(sizable)
}
}
}
import syntax.sizeable._
def ioStatSink[T : Sizeable](): Sink[T, Future[(Long, Long)]] =
Sink.fold((0L, 0L))((acc, bytes) => (acc._1 + 1L, acc._2 + bytes.length))