0

我有一个ArrayBuffer我想将所有对象转换为它们各自大小的现有缓冲区:

trait Obj {
  def size: Int
}

def copySizes(input: ArrayBuffer[Obj], output: ArrayBuffer[Int]): Unit = {
  output.clear()
  input foreach { obj =>
    output += obj.size
  }
}

有没有更好的惯用方式来描述 scala 中的 copySizes ?我在考虑这样的语法:

input.mapTo(_.size, output)
4

2 回答 2

2

你可以

output ++= input.view.map(_.size)

它具有不可忽略的额外开销(~2x 运行时间),但更紧凑。但是,您可以更紧凑地编写您的版本:

input.foreach{ output += _.size }

所以我认为没有太多理由不使用它。

于 2013-05-21T14:42:53.893 回答
1

您是否考虑过尝试使用输出缓冲区作为累加器在输入缓冲区上折叠并在函数体中进行附加?

val output = input.foldLeft(ArrayBuffer[Int]())(_ += _.size)

正如@Rex Kerr 所提到的,与您正在执行的操作相比,这里的性能可能会受到影响foreach,但我不确定这是一个高性能需求的代码。我想这取决于缓冲区中有多少项目以及该代码被命中的频率。如果它的项目数量很少,或者这不是一段始终被命中的代码,那么你可能会更好地使用功能性更强的东西(折叠)而不是更基于副作用的东西(foreach)。

通常在编写 Scala 代码时,您必须做出决定;我关心功能纯度/漂亮的scala代码还是需要优化的东西。我尽可能保持纯粹的功能性,然后对我的系统进行性能测试,找到热点并在需要时进行优化。过早的优化是万恶之源(或类似的东西)=)

于 2013-05-21T14:35:13.220 回答