Performance Scala中类型类的性能

Performance Scala中类型类的性能,performance,scala,typeclass,Performance,Scala,Typeclass,我试图分析在Scala中使用TypeClass的性能成本,因为我注意到当它们被广泛使用时,性能往往会下降。以ByteCodectypeclass为例: trait字节编解码器[T]{ def put(索引:Int,byteBuffer:byteBuffer,t:t):单位 def get(索引:Int,byteBuffer:byteBuffer):T } 然后让我们创建一个Long实例: 对象字节编解码器{ def apply[T](隐式bc:ByteCodec[T]):ByteCodec[T

我试图分析在Scala中使用TypeClass的性能成本,因为我注意到当它们被广泛使用时,性能往往会下降。以
ByteCodec
typeclass为例:

trait字节编解码器[T]{
def put(索引:Int,byteBuffer:byteBuffer,t:t):单位
def get(索引:Int,byteBuffer:byteBuffer):T
}
然后让我们创建一个
Long
实例:

对象字节编解码器{
def apply[T](隐式bc:ByteCodec[T]):ByteCodec[T]=bc
隐式val longBC=新字节编解码器[Long]{
@内联覆盖def put(索引:Int,字节缓冲:字节缓冲,长:长):单位={
val u=byteBuffer.putLong(索引,long)
}
@内联覆盖def get(索引:Int,byteBuffer:byteBuffer):长=
byteBuffer.getLong(索引)
}
}
如果我运行1亿个get和put,那么typeclass测试需要约1200毫秒,否则需要约800毫秒。开销在哪里?我能把它处理掉吗

主设备的代码:

objectmain扩展应用程序{
val周期=100000000
val byteBuffer=byteBuffer.allocate(java.lang.Long.BYTES)
var start=System.currentTimeMillis()
var currCycle=周期
而(电流周期>0){
比特布弗·普特隆(0,10L)
val k=byteBuffer.getLong(0)
currCycle-=1
}
var end=System.currentTimeMillis()
println(s“由缓冲区${end-start}经过的时间”)
val codec=字节编解码器[长]
start=System.currentTimeMillis()
电流周期=周期
而(电流周期>0){
编解码器输出(0,字节缓冲,10L)
val k=codec.get(0,byteBuffer)
currCycle-=1
}
end=System.currentTimeMillis()
println(s“字节编码解码器${end-start}经过的时间”)
}

Aleksey在评论中已经提到了您的测试不准确的一个原因

除此之外,typeclass变慢的主要原因与方法本身无关:是长的装箱/拆箱使它变慢。您可以使用以下命令为值类专门化typeclass:

如果查看
ByteBuffer
中的签名,则使用值类型,不涉及装箱/拆箱:

 public abstract ByteBuffer putLong(int index, long value);
 public abstract long getLong(int index);

取jmh或sbt-jmh进行分析。这里有一个类似问题的指南:。上述幼稚的基准测试至少在
valk=…
中被死掉的代码消除了,并且在背靠背运行测试时出现了预热问题。当然,这是
@专门化的
!我没想过,但现在清楚了。我猜问题是scalac在一种情况下优化了
Long
,而在另一种情况下没有优化。现在我有了类似的性能。注释意味着坏掉的u-基准不报告开销,而不是没有开销。使用专门化的基准之间有什么区别?
 public abstract ByteBuffer putLong(int index, long value);
 public abstract long getLong(int index);