从java到scala集合的隐式转换成本

时间:2015-08-05 10:33:46

标签: java scala collections type-conversion

我想知道从java集合到scala集合的隐式转换成本。在this doc中有几个隐含的双向转换,据说"从源类型转换为目标类型然后再返回将返回原始源对象"

我的结论是成本应该是轻微的(包装),但仍然是多少?

我问这个问题,因为我在一些scala代码中使用了java集合,在导入asScalaSet时我会隐式转换为scala集(我确实在某些地方需要它)。但是,对于非常少的访问者(例如size()

),这可能是一个后续开销

有人知道吗?

2 个答案:

答案 0 :(得分:2)

我决定从实际的角度回答你的问题。我使用以下简单的JMH基准来测试原始scala集合的每秒操作并转换一次(使用隐式转换)。

请查看下面的基准代码:

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()
}

我使用sbt和sbt-jmh插件进行运行。请在下面找到结果:

[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

所以基本上根据结果,确实存在开销。我会尝试继续我的研究,在稍后更新这个问题时提供原因。

如果您希望我为您未来的研究分享完整的sbt项目,请告诉我。

答案 1 :(得分:1)

这是使用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
}

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

实际上,这似乎是一笔不小的费用。