与Seq Var相比,Seq.newBuilder的Scala优势

与Seq Var相比,Seq.newBuilder的Scala优势,scala,scala-collections,Scala,Scala Collections,目前在我的应用程序中,我使用var fooSeq:Seq[Foo]=Seq.empty,然后使用:+来追加项目。我知道这可能会导致多线程问题和潜在的竞争条件,但到目前为止还没有任何问题 我最近发现了Seq.newBuilder(),似乎这可能是使用Scala序列的首选方法。我想知道性能优势是否优于使用vars,以及它可能带来的任何其他类型的优势一般来说,如果您关心线程安全,那么一种常见的方法是使用Java的AtomicReference来包装可变变量,如下所示: val fooSeq:Atomi

目前在我的应用程序中,我使用
var fooSeq:Seq[Foo]=Seq.empty
,然后使用
:+
来追加项目。我知道这可能会导致多线程问题和潜在的竞争条件,但到目前为止还没有任何问题


我最近发现了
Seq.newBuilder()
,似乎这可能是使用Scala序列的首选方法。我想知道性能优势是否优于使用vars,以及它可能带来的任何其他类型的优势一般来说,如果您关心线程安全,那么一种常见的方法是使用Java的
AtomicReference
来包装可变变量,如下所示:

val fooSeq:AtomicReference[Seq[Foo]]=新的AtomicReference(Seq.empty)

如果您需要中间结果,而不是使用构建器,那么这将是更好的方法

如果您不需要中间结果,那么构建器通常会更好。(尽管正如Luis Miguel在评论中提到的,构建器是内部可变的,不一定是线程安全的)

第三种选择是使用Scala的
集合中的可变数据结构:


您可能对以下内容感兴趣:
MutableList
,但是如果这是一个问题,那么仍然需要对线程安全进行
AtomicReference
包装。有些数据结构本机是线程安全的,比如
TrieMap
,它们在
集合中可用。一般来说,如果您关心线程安全,那么一种常见的方法是使用Java的
AtomicReference
包装可变变量,如下所示:

val fooSeq:AtomicReference[Seq[Foo]]=新的AtomicReference(Seq.empty)

如果您需要中间结果,而不是使用构建器,那么这将是更好的方法

如果您不需要中间结果,那么构建器通常会更好。(尽管正如Luis Miguel在评论中提到的,构建器是内部可变的,不一定是线程安全的)

第三种选择是使用Scala的
集合中的可变数据结构:


您可能对以下内容感兴趣:
MutableList
,但是如果这是一个问题,那么仍然需要对线程安全进行
AtomicReference
包装。有些数据结构本机是线程安全的,比如
TrieMap
,这些数据结构在
集合中可用。并发的

所有构建器都是强制增量构建集合的最快方法。但是,除非包含在单个方法的范围内,否则它们的易变性可能是危险的。另外,另一个问题是构建器不是集合,因此您必须在最后调用
result()
(我相信这就是它的调用方式),因此您不能使用中间步骤;可以在
var
中使用不可变集合。所有构建器都将是强制增量构建集合的最快方式。但是,除非包含在单个方法的范围内,否则它们的易变性可能是危险的。另外,另一个问题是构建器不是集合,因此您必须在最后调用
result()
(我相信这就是它的调用方式),因此您不能使用中间步骤;您可以使用
var
中的不可变集合来实现“Scala的一个奇怪之处是它们可以声明为val”,这有什么奇怪之处“这些在collections.concurrent中可用”,AFAIK
collections.concurrent
不应使用,而应退回到Java中。在haskell中,您需要将可变值包装在Monad这样的状态中,以实现可变性。“val”在不变性方面具有误导性。
val
表示引用是不可变的,这意味着变量的值不能更改。如果值是内部可变的,则超出了该范围。当然,这是Scala中“val/var”的更准确描述,但是“val”通常被描述为“不可变”,没有任何警告。谢谢你们两位的评论,从你们两位那里学到了一些东西。我认为Seq.newBuilder()不适合我,因为我确实需要对我的Seq执行中间步骤,Fabian我将研究您提供的一些资源。谢谢“Scala的一个奇怪之处是它们可以被声明为val”,这有什么奇怪之处“这些在collections.concurrent中可用”,AFAIK
collections.concurrent
不应使用,而应退回到Java中。在haskell中,您需要将可变值包装在Monad这样的状态中,以实现可变性。“val”在不变性方面具有误导性。
val
表示引用是不可变的,这意味着变量的值不能更改。如果值是内部可变的,则超出了该范围。当然,这是Scala中“val/var”的更准确描述,但是“val”通常被描述为“不可变”,没有任何警告。谢谢你们两位的评论,从你们两位那里学到了一些东西。我认为Seq.newBuilder()不适合我,因为我确实需要对我的Seq执行中间步骤,Fabian我将研究您提供的一些资源。谢谢