gpt4 book ai didi

Scala 类型标签和性能

转载 作者:行者123 更新时间:2023-12-04 18:43:22 26 4
gpt4 key购买 nike

关于 Java 的等效问题有一些答案,但是 scala 反射(2.11,TypeTags)真的很慢吗?在 http://docs.scala-lang.org/overviews/reflection/overview.html 上有一篇关于它的长篇叙述文章。 ,这个问题的答案很难提取。

我看到很多关于避免反射的建议,其中一些可能早于 2.11 的改进,但如果它运作良好,它看起来可以解决 JVM 类型删除的衰弱方面,对​​于 Scala 代码。

谢谢!

最佳答案

让我们测量一下。我创建了具有一种方法的简单 class C。此方法所做的只是休眠 10 毫秒。让我们调用这个方法

  • 反射(reflection)

  • 直接

看看哪个更快,速度有多快。

我已经创建了三个测试。

测试 1。 通过反射调用。执行时间包括设置反射所需完成的所有工作。创建 runtimeMirror,反射(reflect)类,创建方法声明,最后一步 - 执行方法。

测试 2。不要考虑这个准备阶段,因为它可以重复使用。我们仅通过反射计算方法调用的时间。

测试 3. 直接调用方法。

结果:

Reflection from start : job done in 2561ms got 101 (1,5seconds for setup each execution)

Invoke method reflection: job done in 1093ms got 101 ( < 1ms for setup each execution)

No reflection: job done in 1087ms got 101 ( < 1ms for setup each execution)

结论:设置阶段会显着增加执行时间。但是不需要在每次执行时都进行设置(这就像类初始化——可以完成一次)。因此,如果您以正确的方式使用反射(使用分离的初始化阶段),它会显示出相关的性能并可用于生产。

源代码:

    class C {
def x = {
Thread.sleep(10)
1
}
}


class XYZTest extends FunSpec {
def withTime[T](procName: String, f: => T): T = {
val start = System.currentTimeMillis()
val r = f
val end = System.currentTimeMillis()
print(s"$procName job done in ${end-start}ms")
r
}

describe("SomeTest") {
it("rebuild each time") {
val s = withTime("Reflection from start : ", (0 to 100). map {x =>
val ru = scala.reflect.runtime.universe
val m = ru.runtimeMirror(getClass.getClassLoader)
val im = m.reflect(new C)
val methodX = ru.typeOf[C].declaration(ru.TermName("x")).asMethod
val mm = im.reflectMethod(methodX)
mm().asInstanceOf[Int]
}).sum
println(s" got $s")
}
it("invoke each time") {
val ru = scala.reflect.runtime.universe
val m = ru.runtimeMirror(getClass.getClassLoader)
val im = m.reflect(new C)
val s = withTime("Invoke method reflection: ", (0 to 100). map {x =>
val methodX = ru.typeOf[C].declaration(ru.TermName("x")).asMethod
val mm = im.reflectMethod(methodX)
mm().asInstanceOf[Int]
}).sum
println(s" got $s")
}
it("invoke directly") {
val c = new C()
val s = withTime("No reflection: ", (0 to 100). map {x =>
c.x
}).sum
println(s" got $s")
}
}
}

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

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