gpt4 book ai didi

Scala 中类型类的性能

转载 作者:行者123 更新时间:2023-12-04 02:37:02 25 4
gpt4 key购买 nike

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

trait ByteCodec[T] {
def put(index: Int, byteBuffer: ByteBuffer, t: T): Unit
def get(index: Int, byteBuffer: ByteBuffer): T
}

然后让我们创建一个 Long 实例:

object ByteCodec {
def apply[T](implicit bc: ByteCodec[T]): ByteCodec[T] = bc

implicit val longBC = new ByteCodec[Long] {
@inline override def put(index: Int, byteBuffer: ByteBuffer, long: Long): Unit = {
val _ = byteBuffer.putLong(index, long)
}

@inline override def get(index: Int, byteBuffer: ByteBuffer): Long =
byteBuffer.getLong(index)
}
}

如果我运行 1 亿次获取和放置,类型类测试需要大约 1200 毫秒,否则需要大约 800 毫秒。开销在哪里,我可以摆脱它吗?

主要代码:

object Main extends App {
val cycles = 100000000
val byteBuffer = ByteBuffer.allocate(java.lang.Long.BYTES)
var start = System.currentTimeMillis()
var currCycle = cycles
while (currCycle > 0) {
byteBuffer.putLong(0, 10L)
val k = byteBuffer.getLong(0)
currCycle -= 1
}
var end = System.currentTimeMillis()
println(s"time elapsed byteBuffer ${ end - start }")

val codec = ByteCodec[Long]
start = System.currentTimeMillis()
currCycle = cycles
while (currCycle > 0) {
codec.put(0, byteBuffer, 10L)
val k = codec.get(0, byteBuffer)
currCycle -= 1
}
end = System.currentTimeMillis()
println(s"time elapsed ByteCodec ${ end - start }")
}

最佳答案

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

除此之外,您的类型类较慢的主要原因与方法本身无关:它是 Longs 的装箱/拆箱使其变慢的原因。您可以使用 @specialized annotation 为值类专门化您的类型类:

trait ByteCodec[@specialized(Long) T]

如果您看一下 ByteBuffer 的签名,就会使用值类型并且不涉及装箱/拆箱:

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

关于Scala 中类型类的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36477373/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com