【问题标题】:Hibernate implementation. Are we paying the reflection penalty?休眠实现。我们是否支付了反射惩罚?
【发布时间】:2010-10-07 13:38:13
【问题描述】:

很久以前,我正在使用反射创建一个迷你 ORM。

在阅读有关反射时,我得到了类似的答案:

Java Reflection Performance

这完全有道理,我退出了我的迷你 orm 并锐化了我的 CTRL+C、CTRL+V 键(该库旨在避免不得不为网络应用程序中的不同表一次又一次地重写相同的 sn-ps 我正在努力)

几年后由于某种原因我现在不记得(也不想记住)我正在阅读(或试图...)Hibernate 源代码,因为我想知道他们是否使用 AOP 在飞行并避免反射惩罚,但令我惊讶的是,我所看到的都是纯粹的反射。

这是否意味着最被接受的 ORM 框架,究竟是几年前阻止我继续我幼稚的努力? :")

我的问题是:有人可以确认我对 Hibernate 实现的理解吗?他们是否会即时生成字节码以提高性能?还是我们(当我们使用它时)总是支付反射惩罚(顺便说一句,如果差异在几毫秒内,我们都没有注意到或抱怨)

我们是否支付了反射惩罚?如果是,我认为它是值得的!!!

问候。

【问题讨论】:

    标签: java hibernate reflection


    【解决方案1】:

    使用 NHibernate 确实付出了反射代价,但如果你通过 NHibernate.Bytecode.IBytecodeProvider 提供所有优化的反射实现,它的可扩展性允许你避免 90% 的反射损失。

    【讨论】:

      【解决方案2】:

      Hibernate 让您的模型具备休眠感知能力。

      使用反射有不同程度的成本。不断查找特定类的方法特别昂贵。使用缓存副本通过反射执行方法并没有那么慢。如果考虑到反射 api 必须完成的任务以调用该方法,那么每个部分都很慢并且消耗 cpu 周期是有道理的。

      定位方法

      • 访问特定类的每个方法
      • 测试每个方法的可见性、方法签名等。
      • found 方法生成字节码。

      一个典型类中的方法数量的一个因素以及其中一些操作并非微不足道,很明显这可能是昂贵的。

      调用方法。

      每个反射方法相当于一段字节码,它调用目标方法并带有一些样板文件以匹配反射接口。在它可以这样做之前,它必须执行一些健全性检查,以便它可以抱怨漂亮的消息,而不是让运行时抛出 ClassCastException 和类似的异常。

      • 如果实例方法检查传入的实例不是 null 并且是正确的类型。
      • 检查 arguments 参数是否包含正确数量和类型的参数。
      • 在 try catch 中执行该方法。在接球 ITE 等中。

      所有这些额外的东西都会增加一些成本 - 不是很多,但它确实让事情变得更慢。

      运行时成本

      在一般的缓存方法和调用这不是成本,但有点慢。反射 api 本身确实会尝试缓存方法和类,但找到正确的方法等仍然是一个缓慢的操作。

      【讨论】:

        【解决方案3】:

        持久化和检索的成本是反射成本的许多倍。从数据库访问一条记录可能需要 1-10 毫秒,而使用反射构造一个对象可能需要 0.001 到 0.01 毫秒。

        【讨论】:

        • 我最近遇到了一个与您的说法完全不同的问题:stackoverflow.com/questions/8573636/…。在访问一条记录时,您可能是对的,但总的来说,开销是不可忽略的,看起来......
        【解决方案4】:

        我认为要记住的重要一点是整个应用程序的相对成本。反射比普通对象创建慢吗?是的。反射变得更好更快了吗?是的。但实际上,在比较反射成本与通过线路并使用数据库做某事时,这些点并不是很重要,这就是 hibernate 所做的 - 成本变得完全可以忽略不计,我会说我们没有付出代价。

        【讨论】:

          【解决方案5】:

          NHibernate 不会缓存通过反射收集的类信息,因此您只需在第一次支付罚金吗?

          【讨论】:

          • 但是每次从数据库中加载一个对象时,setters 方法都应该被反射性地调用(即使方法引用被缓存了)授予 NHibernate 的实现方式与 Hibernate 相同。
          猜你喜欢
          • 1970-01-01
          • 2011-01-25
          • 2019-10-18
          • 2012-05-12
          • 1970-01-01
          • 2016-12-29
          • 2020-07-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多