【问题标题】:Fastest way to get the names of the fields of a case class in Scala在Scala中获取案例类字段名称的最快方法
【发布时间】:2014-05-27 08:14:44
【问题描述】:

这与以下问题有关:In scala, how to turn object's values into Map[String, String]?

事实上,我也有几乎完全相同的问题。但是,在我的机器上迭代 1000 次(或手动编写函数以返回 (key, value)对)。在Scala中获取案例类的字段名称是否有合理的性能和简洁的方法?对我来说,核心语言会提供一种类似于高性能反射的方式来获取值而不是字段名称,这对我来说似乎很奇怪。

【问题讨论】:

标签: scala reflection


【解决方案1】:

如果你编写和编译一个案例类,你可以浏览生成的字节码,你会注意到字段名称没有硬编码到类的方法中。这意味着您必须使用反射来找出这些名称。不幸的是,反射查找很昂贵。

对于productIterator,有一种方法可以避免反射。任何案例类都实现了Product trait,它定义了一个方法Object productElement(int),它将返回给定索引处的字段值。除了字段名称,此信息被硬编码到案例类方法中。通过内部使用该方法,productIterator方法避免了反射,可以高效执行。

底线:虽然反射调用不是那么昂贵,但反射查找却是。如果您需要字段名称信息,因此您应该只查找一次信息并缓存结果以供以后重复使用。

【讨论】:

  • 有没有办法确保成员按照声明的顺序出现,就像productIterator 一样?我在Type 类中看到了一些关于declarations.sorted 的内容,但找不到关于排序顺序的明确说明。
  • 理论上,使用反射调用时,所有字段都应按源代码的顺序出现。然而,这没有指定,JVM 可能会选择以不同的方式实现它。然而,一旦你通过反射查找,反射字段读取是非常便宜的。 IT 基本上是直接堆访问,与本机字段访问相比,您不会注意到任何运行时差异。这样,您还可以在适用的情况下检索未装箱的实例,甚至可以节省您的时间。
  • 尽管我还没有看到字段排序的反例,但如果 api 特意说订单未指定,我非常担心在生产中依赖它。对于sorted,我还没有找到描述排序顺序的规范。
  • 你在哪里发现了Type这个declarations.sorted
  • scala api: abstract def members: Universe.MemberScope 包含此类型的所有成员(直接声明或继承)的范围。与声明不同,此方法还返回继承的成员。返回范围内的成员可能以任意顺序出现。使用 declarations.sorted 获取有序的成员列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 2011-02-09
  • 2016-09-07
相关资源
最近更新 更多