几次调用Method/Field.getAnnotation(Class)与在Map中预缓存此数据的性能

Gab*_*res 15 java reflection performance annotations map

我想知道是否有关于重复调用(在Java中)Method.getAnnotation(Class)Field.getAnnotation(Class)方法的性能的比较/研究,与存储(在程序启动时)一个预先计算的Map以及类的元数据信息并重复查询它后来.哪一个可以提供最佳的运行时性能?

在Java 5,6和7下,这种性能是一样的吗?

小智 11

地图应该是更好的方法.主要问题不仅仅是缓存.而且还改善了多线程争用.在Method.getAnnotation()中,它调用synchronizedAnnotations()的同步私有方法.同步方法对高线程应用程序有不良影响.

  • 在一个多线程的Java EE应用程序中,`getAnnotation`被称为18k次,通过使用`ConcurrentHasMap`进行缓存,测得的墙上时间从3.7s下降到0.09s. (6认同)

San*_*rma 1

我想这在一定程度上取决于 JVM 的实现。但以 Oracle JVM 为例,它维护了方法和字段实例上所有注释的缓存,这相当于你所说的映射方法。

但这里有一个问题:由于方法/字段实例对于每个对象都是唯一的,如果您最终为给定类创建大量对象,您几乎会失去所提供的性能优势。在这种情况下,类名+方法名/类名+字段名到相关注释列表的静态映射胜过所使用的内置缓存方法。

顺便说一句,你是如何预先计算地图的?是在应用程序启动时完成还是在某些自动生成的代码中完成?您是否真的确认在您的案例中缓存注释实例是安全的?

与往常一样,对于此类问题,最好的解决方案是使用您的应用程序在线进行分析/测量,并采用在给定用例中看起来像是胜利的解决方案。