简体   繁体   English

从 Java 到 Scala 集合的隐式转换成本

[英]Cost of implicit conversion from java to scala collections

I'd like to know the cost of implicit conversion from java collection to scala ones.我想知道从 java 集合到 Scala 集合的隐式转换的成本。 In this doc there are several implicit two-way conversions for which it is said that "converting from a source type to a target type and back again will return the original source object" .本文档中,有几个隐式双向转换,据说“从源类型转换为目标类型并再次返回将返回原始源对象”

I conclude that the cost should be minor (wrapping), but still how much is it?我的结论是成本应该很小(包装),但它仍然是多少?

I ask this question because I use java sets in some scala code, which is implicitly converted to scala set as I import asScalaSet (I do need it in some places).我问这个问题是因为我在一些 Scala 代码中使用了 java 集,当我导入asScalaSet ,它被隐式转换为 Scala 集(我在某些地方确实需要它)。 However, it might be a consequent overhead for very little accessors such as size()但是,对于很少的访问器(例如size() ,这可能是随之而来的开销

Does anyone know?有人知道吗?

I decided to answer your question from practical point of view.我决定从实际的角度回答你的问题。 I used the following simple JMH benchmarks to test operations per second for original scala collection and converted one (using implicit conversion).我使用以下简单的 JMH 基准测试原始 Scala 集合的每秒操作数并转换一个(使用隐式转换)。

Please find below code of benchmark:请找到以下基准代码:

import org.openjdk.jmh.annotations._

import scala.collection.JavaConversions._

@State(Scope.Thread)
class WrapperBenchmark {

  val unwrappedCollection = (1 to 100).toSet
  val wrappedCollection: java.util.Set[Int] = (1 to 100).toSet[Int]

  @Benchmark
  def measureUnwrapped: Int = unwrappedCollection.size

  @Benchmark
  def measureWrapped: Int = wrappedCollection.size()
}

I used sbt and sbt-jmh plugin for running.我使用 sbt 和 sbt-jmh 插件运行。 Please find results below:请在下面找到结果:

[info] Benchmark                           Mode  Cnt          Score         Error  Units
[info] WrapperBenchmark.measureUnwrapped  thrpt  200  353214968.844 ± 1534779.932  ops/s
[info] WrapperBenchmark.measureWrapped    thrpt  200  284669396.241 ± 4223983.126  ops/s

So basically according to results, there is overhead indeed.所以基本上根据结果,确实有开销。 I will try to continue my research providing the reason why it is like this in later update to this question.我将尝试继续我的研究,在此问题的后续更新中提供为什么会这样。

Please let me know if you want me to share complete sbt project for your future research.如果您希望我为您未来的研究分享完整的 sbt 项目,请告诉我。

Here are jmh benchmark results using Scala 2.13.1 CollectionConverters以下是使用 Scala 2.13.1 CollectionConverters jmh 基准测试结果

import org.openjdk.jmh.annotations._
import scala.jdk.CollectionConverters._
import java.{util => ju}

@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.Throughput))
class So31830028 {
  val size = 1000000
  val scalaSet: Set[Int] = (1 to size).toSet
  val javaSet: ju.Set[Int]  = (1 to size).toSet.asJava

  @Benchmark def scala = scalaSet.size
  @Benchmark def scalaAsJava = scalaSet.asJava.size
  @Benchmark def java = javaSet.size
  @Benchmark def javaAsScala = javaSet.asScala.size
}

where sbt "jmh:run -i 10 -wi 5 -f 2 -t 1 bench.So31830028" gives其中sbt "jmh:run -i 10 -wi 5 -f 2 -t 1 bench.So31830028"给出

[info] Benchmark                     Mode  Cnt          Score          Error   Units
[info] So31830028.java              thrpt   20  356515729.840 ± 64691657.672   ops/s
[info] So31830028.javaAsScala       thrpt   20  270053471.338 ± 36854051.611   ops/s
[info] So31830028.scala             thrpt   20  448415156.726 ± 53674976.259   ops/s
[info] So31830028.scalaAsJava       thrpt   20  211808793.234 ± 57898858.737   ops/s

Indeed there seems to be a rather significant cost.事实上,似乎有相当大的成本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM