Seq.newBuilder 相对于 Seq 变量的 Scala 优势
Scala advantages of Seq.newBuilder over Seq vars
目前在我的应用程序中,我使用 var fooSeq: Seq[Foo] = Seq.empty
然后使用 :+
来附加项目。我知道这可能会导致多线程问题和潜在的竞争条件,但到目前为止还没有任何问题。
我最近发现 Seq.newBuilder()
并且似乎这可能是使用 Scala 序列的首选方式。我想知道性能优势是否优于使用 vars,以及它可能带来的任何其他类型的优势
一般来说,如果您关心线程安全,那么常见的方法是使用 Java 的 AtomicReference
来包装您的可变变量,如下所示:
val fooSeq: AtomicReference[Seq[Foo]] = new AtomicReference(Seq.empty)
如果您需要中间结果而不是使用生成器,那将是更好的方法。
如果您不需要中间结果,那么 Builders 通常更好。 (尽管正如 Luis Miguel 在评论中提到的那样,构建器在内部是可变的,不一定是线程安全的)
第三种选择是使用 Scala collections
中的可变数据结构:https://docs.scala-lang.org/overviews/collections/performance-characteristics.html
您可能对以下内容感兴趣:MutableList
,但是如果这是一个问题,这仍然需要 AtomicReference
线程安全包装。有一些数据结构本身是线程安全的,比如 TrieMap
并且在 collections.concurrent
中可用
目前在我的应用程序中,我使用 var fooSeq: Seq[Foo] = Seq.empty
然后使用 :+
来附加项目。我知道这可能会导致多线程问题和潜在的竞争条件,但到目前为止还没有任何问题。
我最近发现 Seq.newBuilder()
并且似乎这可能是使用 Scala 序列的首选方式。我想知道性能优势是否优于使用 vars,以及它可能带来的任何其他类型的优势
一般来说,如果您关心线程安全,那么常见的方法是使用 Java 的 AtomicReference
来包装您的可变变量,如下所示:
val fooSeq: AtomicReference[Seq[Foo]] = new AtomicReference(Seq.empty)
如果您需要中间结果而不是使用生成器,那将是更好的方法。
如果您不需要中间结果,那么 Builders 通常更好。 (尽管正如 Luis Miguel 在评论中提到的那样,构建器在内部是可变的,不一定是线程安全的)
第三种选择是使用 Scala collections
中的可变数据结构:https://docs.scala-lang.org/overviews/collections/performance-characteristics.html
您可能对以下内容感兴趣:MutableList
,但是如果这是一个问题,这仍然需要 AtomicReference
线程安全包装。有一些数据结构本身是线程安全的,比如 TrieMap
并且在 collections.concurrent