尽管是包装器,但CollectionConverters的性能如何?

问题描述 投票:4回答:1

[AFAIU,CollectionConverters是包装器,只是将对底层集合的调用委派给用户,因此代价应该是单个对象分配,然后是单个方法调用间接,例如,CollectionConverters状态

内部,这些转换通过设置“包装器”对象来完成将所有操作转发到基础集合对象。所以在Java和Scala之间进行转换时,集合从不复制

分析Conversion Between Java and Scala Collections实际上我们看到它只是将调用委派给SetWrapper集合

SetWrapper

但是,请考虑以下jmh基准

underlying

class SetWrapper[A](underlying: Set[A]) extends ju.AbstractSet[A] with Serializable { self => ... def size = underlying.size ... } 给出的位置>

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

[AFAIU,CollectionConverters是包装器,只是将对底层集合的调用委托给包装器,因此代价应该是单个对象分配,然后是单个方法调用间接,例如,...

scala performance wrapper scala-collections scala-java-interop
1个回答
1
投票

在2.12中,CollectionConvertersCost of implicit conversion from java to scala collections;对于2.13,它是对scalaSet.size的简单字段访问器调用,应该很容易内联,因此

© www.soinside.com 2019 - 2024. All rights reserved.