Scala的.map()函数在不可变和可变的映射上

时间:2014-11-27 18:15:22

标签: scala immutability mutable

在较长的地图上调用.map()时会更快

  1. 在可变地图上调用
  2. 在不可变的地图上调用
  3. 或者它没有什么区别

1 个答案:

答案 0 :(得分:5)

让我们检查它(当然,微基准测试结果应该总是带着一点点盐)。

使用Scalameter

// build.sbt

scalaVersion := "2.11.4"

libraryDependencies ++= Seq(
    "com.storm-enroute" %% "scalameter" % "0.6"
)

// src/main/scala/main.scala

import org.scalameter.api._
import scala.collection.immutable
import scala.collection.mutable

object RangeBenchmark extends PerformanceTest.Quickbenchmark {
  val sizes = Gen.range("size")(100000, 500000, 100000)

  val immutableMaps = for {
    size <- sizes
  } yield immutable.Map((0 until size).map(n => n -> (size-n)).toSeq: _*)

  val mutableMaps = for {
    size <- sizes
  } yield mutable.Map((0 until size).map(n => n -> (size-n)).toSeq: _*)

  performance of "immutable.Map" in {
    measure method "map" in {
      using(immutableMaps) in { m => m.map { case (k, v) => (k+1, v+1) } }
    }
  }

  performance of "mutable.Map" in {
    measure method "map" in {
      using(mutableMaps) in { m => m.map { case (k, v) => (k+1, v+1) } }
    }
  }
}

正在运行(sbt run):

... lots of output ...

::Benchmark immutable.Map.map::
cores: 4
jvm-name: OpenJDK 64-Bit Server VM
jvm-vendor: Oracle Corporation
jvm-version: 24.65-b04
os-arch: amd64
os-name: Linux
Parameters(size -> 100000): 40.95331
Parameters(size -> 200000): 90.12223
Parameters(size -> 300000): 139.716564
Parameters(size -> 400000): 208.114459
Parameters(size -> 500000): 254.876849

... lots of output ...

::Benchmark mutable.Map.map::
cores: 4
jvm-name: OpenJDK 64-Bit Server VM
jvm-vendor: Oracle Corporation
jvm-version: 24.65-b04
os-arch: amd64
os-name: Linux
Parameters(size -> 100000): 24.004582
Parameters(size -> 200000): 52.941946
Parameters(size -> 300000): 66.036803
Parameters(size -> 400000): 113.575799
Parameters(size -> 500000): 119.544183

显然,可变地图几乎快两倍。我的猜测是,这是因为map Builder的不同之处:不可变映射构建器是var,它使用每个添加的元素进行更新,而可变映射构建器是可变映射本身。因此,对于较大的映射大小,不可变映射构建器会导致更多分配。这真是一个疯狂的猜测,所以也许更有知识的人会给出正确的理由。