首页 > 解决方案 > 创建新地图或清除它并再次使用会更快吗?

问题描述

我需要在我的项目中使用许多地图,所以我想知道哪种方式更有效:

val map = mutable.Map[Int, Int] = mutable.Map.empty
for (_ <- 0 until big_number)
  {
    // do something with map
    map.clear()
  }

或者

for (_ <- 0 until big_number)
  {
    val map = mutable.Map[Int, Int] = mutable.Map.empty
    // do something with map
  }

在时间和内存方面使用?

标签: scalaperformance

解决方案


好吧,我的正式回答总是取决于。因为您需要对自己的方案进行基准测试,并查看更适合您的方案的方案。我将提供一个示例,您可以如何尝试对自己的代码进行基准测试。让我们从编写测量方法开始:

def measure(name: String, f: () => Unit): Unit = {
  val l = System.currentTimeMillis()
  println(name + ": " + (System.currentTimeMillis() - l))
  f()
  println(name + ": " + (System.currentTimeMillis() - l))
}

假设在每次迭代中,我们需要在映射中插入一个键值对,然后打印它:

Await.result(Future.sequence(Seq(Future {
  measure("inner", () => {
    for (i <- 0 until 10) {
      val map2 = mutable.Map.empty[Int, Int]
      map2(i) = i
      println(map2)
    }
  })
},
Future {
  measure("outer", () => {
    val map1 = mutable.Map.empty[Int, Int]
    for (i <- 0 until 10) {
      map1(i) = i
      println(map1)
      map1.clear()
    }
  })
})), 10.seconds)

在这种情况下,输出在inner和 之间几乎总是相等的outer。请注意,在这种情况下,我并行运行这两个选项,就好像我不会总是花费更多时间,无论其中哪个是第一个。

因此,我们可以得出结论,在这种情况下,它们几乎相同。

但是,例如,如果我添加一个不可变的选项:

Future {
  measure("immutable", () => {
    for (i <- 0 until 10) {
      val map1 = Map[Int, Int](i -> i)
      println(map1)
    }
  })
}

它总是首先结束。这是有道理的,因为不可变集合比可变集合具有更高的性能。

为了获得更好的性能测试,您可能需要使用一些第三方,例如scalameter或其他存在的。


推荐阅读