加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala TypeTags和性能

发布时间:2020-12-16 10:05:11 所属栏目:安全 来源:网络整理
导读:关于 Java的等价问题有一些答案,但是scala反射(2.11,TypeTags)真的很慢吗?在 http://docs.scala-lang.org/overviews/reflection/overview.html有关于它的长篇叙述性文章,这个问题的答案难以提取. 我看到很多关于避免反射的建议,可能其中一些早于2.11的改进,
关于 Java的等价问题有一些答案,但是scala反射(2.11,TypeTags)真的很慢吗?在 http://docs.scala-lang.org/overviews/reflection/overview.html有关于它的长篇叙述性文章,这个问题的答案难以提取.

我看到很多关于避免反射的建议,可能其中一些早于2.11的改进,但是如果这很好用,看起来它可以解决JVM类型擦除的衰弱方面,对??于scala代码.

谢谢!

解决方法

我们来衡量吧.
我创建了一个简单的C类,它有一个方法.这种方法所做的就是睡10ms.
我们来调用这个方法

>在反思中
>直接

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

我创造了三个测试.

测试1.通过反射调用.执行时间包括设置反射所需的所有工作.
创建runtimeMirror,反映类,为方法创建声明,最后一步 – 执行方法.

测试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")
        }
      }
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读