Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从java到scala集合的隐式转换成本_Java_Scala_Performance_Collections_Type Conversion - Fatal编程技术网

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

从java到scala集合的隐式转换成本,java,scala,performance,collections,type-conversion,Java,Scala,Performance,Collections,Type Conversion,我想知道从java集合到scala集合的隐式转换的成本。在中,有几种隐式双向转换,据说“从源类型转换为目标类型,然后再转换回来将返回原始源对象” 我的结论是,成本应该很低(包装),但还是多少钱 我问这个问题是因为我在一些scala代码中使用java集,在导入asScalaSet时,java集被隐式转换为scala集(在某些地方我确实需要它)。但是,对于非常少的访问器,例如size() 有人知道吗?我决定从实际的角度回答你的问题。我使用以下简单的JMH基准测试原始scala集合和转换的scala集

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

我的结论是,成本应该很低(包装),但还是多少钱

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


有人知道吗?

我决定从实际的角度回答你的问题。我使用以下简单的JMH基准测试原始scala集合和转换的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项目,请告诉我。

以下是使用Scala 2.13.1的jmh基准测试结果

其中
sbt“jmh:run-i10-wi5-f2-t1试验台。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

确实,这似乎是一个相当大的成本。

我不知道编译器有多聪明,但在很多情况下,它似乎应该能够避免分配包装类、内联调用(如
size
),并且不会产生任何开销?这不是对你的问题的回答,而是通常的“魔力”JavaConversion有点不受欢迎,而倾向于更显式的转换,这需要您编写.asScala或.asJava来实现显式转换。Good info@RüdigerKlaehn。这确实很有用,这样至少我可以控制转换发生的时间。来自python的背景,我只能同意这一点(“显式优于隐式”-python的禅宗)对于鱼和鱼竿的Tx:-)我现在不会再深入研究它,但你给了我工具来回答我可能遇到的类似问题。请随意分享这样一个sbt项目,以对简单功能进行基准测试。您的基准测试功能创建了集合,因此您对[create+wrapping]进行基准测试,显然,创建要比wrapping长得多。您能在之前创建一次初始集吗:
classso318{val set=(1到1000000)。toSet;val javaSet=set.asJava;def scala=set.size;def scalaAsJava=javaSet.size}
。另外,请注意,我的问题是关于另一种方式:在java集上使用scala包装器的成本,而不是直接在java集上使用。@Juh_u确实您是对的。谢谢你指出错误!请参阅编辑后的答案以获取更新结果。
[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