Scala Stream vs Scala List vs Scala Sequence 有什么区别 [英] what is the difference between Scala Stream vs Scala List vs Scala Sequence

查看:55
本文介绍了Scala Stream vs Scala List vs Scala Sequence 有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个场景,我以对象流的形式获取数据库数据.并且在将其转换为 Object 序列时需要时间.我正在寻找花费更少时间的替代方案.

I have a scenario where i get DB data in the form of Stream of Objects. and while transforming it into a sequence of Object it is taking time. I am looking for alternative which takes less time.

推荐答案

快速回答:Scala 流 已经是一个 Scala 序列,不需要在全部.下面进一步解释...

Quick answer: a Scala stream is already a Scala sequence and does not need to be converted at all. Further explanation below...

Scala 序列 (scala.collection.Seq) 只是任何以特定顺序存储元素序列的集合(顺序是任意的,但元素顺序一旦定义就不会改变).

A Scala sequence (scala.collection.Seq) is simply any collection that stores a sequence of elements in a specific order (the ordering is arbitrary, but element order doesn't change once defined).

Scala 列表 (scala.collection.immutable.List) 是 Seq 的子类,也是 Seq 的默认实现代码>scala.collection.Seq.也就是说,Seq(1, 2, 3) 被实现为一个 List(1, 2, 3).Lists 是严格的,因此对列表的任何操作都会处理所有元素,一个接一个,然后才能执行另一个操作.

A Scala list (scala.collection.immutable.List) is a subclass of Seq and is also the default implementation of a scala.collection.Seq. That is, Seq(1, 2, 3) is implemented as a List(1, 2, 3). Lists are strict, so any operation on a list processes all elements, one after the other, before another operation can be performed.

例如,考虑 Scala REPL 中的这个例子:

For example, consider this example in the Scala REPL:

$ scala
Welcome to Scala 2.12.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_171).
Type in expressions for evaluation. Or try :help.

scala> val xs = List(1, 2, 3)
xs: List[Int] = List(1, 2, 3)

scala> xs.map {x =>
     |   val newX = 2 * x
     |   println(s"Mapping value $x to $newX...")
     |   newX
     | }.foreach {x =>
     |   println(s"Printing value $x")
     | }
Mapping value 1 to 2...
Mapping value 2 to 4...
Mapping value 3 to 6...
Printing value 2
Printing value 4
Printing value 6

注意每个值是如何映射的,创建一个新列表(List(2, 4, 6)),之前打印该新列表的任何值出来了吗?

Note how each value is mapped, creating a new list (List(2, 4, 6)), before any of the values of that new list are printed out?

一个Scala流(scala.collection.immutable.Stream)也是Seq的子类,但它懒惰(或非严格),意味着流中的下一个值仅在需要时才被采用.它通常被称为懒惰列表.

A Scala stream (scala.collection.immutable.Stream) is also a subclass of Seq, but it is lazy (or non-strict), meaning that the next value from the stream is only taken when required. It is often referred to as a lazy list.

为了说明 StreamList 之间的区别,让我们重做这个例子:

To illustrate the difference between a Stream and a List, let's redo that example:

scala> val xs = Stream(1, 2, 3)
xs: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> xs.map {x =>
     |   val newX = 2 * x
     |   println(s"Mapping value $x to $newX...")
     |   newX
     | }.foreach {x =>
     |   println(s"Printing value $x")
     | }
Mapping value 1 to 2...
Printing value 2
Mapping value 2 to 4...
Printing value 4
Mapping value 3 to 6...
Printing value 6

注意,对于Stream,我们只在前一个元素的所有操作完成后才处理下一个map操作?Map 操作仍然返回一个新的流(Stream(2, 4, 6)),但仅在需要时才取值.

Note how, for a Stream, we only process the next map operation after all of the operations for the previous element have been completed? The Map operation still returns a new stream (Stream(2, 4, 6)), but values are only taken when needed.

在任何特定情况下 Stream 是否比 List 表现更好将取决于您尝试做什么.如果性能是您的主要目标,我建议您对代码进行基准测试(使用诸如 ScalaMeter 之类的工具)) 以确定哪种类型最有效.

Whether a Stream performs better than a List in any particular situation will depend upon what you're trying to do. If performance is your primary goal, I suggest that you benchmark your code (using a tool such as ScalaMeter) to determine which type works best.

顺便说一句,由于 StreamList 都是 Seq 的子类,通常的做法是编写需要序列来利用 <代码>序列.这样,您可以提供 List or 一个 Stream 任何其他 Seq子类,无需更改代码,也无需将列表、流等转换为序列.例如:

BTW, since both Stream and List are subclasses of Seq, it is common practice to write code that requires a sequence to utilize Seq. That way, you can supply a List or a Stream or any other Seq subclass, without having to change your code, and without having to convert lists, streams, etc. to sequences. For example:

def doSomethingWithSeq[T](seq: Seq[T]) = {
  //
}

// This works!
val list = List(1, 2, 3)
doSomethingWithSeq(list)

// This works too!
val stream = Stream(4, 5, 6)
doSomethingWithSeq(stream)

更新

ListStream 对于 groupBy 操作的性能将非常相似.根据它的使用方式,Stream 可能需要比 List 更少的内存,但可能需要一点额外的 CPU 时间.如果收集性能绝对是问题,请对两种类型的收集进行基准测试(见上文)并精确测量以确定两者之间的权衡.我不能替你下定决心.您提到的缓慢可能是由于数据库和您的应用程序之间的数据传输造成的,与集合类型无关.

The performance of List vs. Stream for a groupBy operation is going to be very similar. Depending upon how it's used, a Stream can require less memory than a List, but might require a little extra CPU time. If collection performance is definitely the issue, benchmark both types of collection (see above) and measure precisely to determine the trade-offs between the two. I cannot make that determination for you. It's possible that the slowness you refer to is down to the transmission of data between the database and your application, and has nothing to do with the collection type.

有关 Scala 集合性能的一般信息,请参阅 集合:性能特征.

For general information on Scala collection performance, refer to Collections: Performance Charateristics.

更新 2

另请注意,任何类型的 Scala 序列通常一次由一个线程按顺序处理(因此得名).ListStream 都不适合对其元素进行并行处理.如果您需要并行处理一个集合,您将需要一个 parallel 集合类型(scala.collection.parallel 中的集合之一).scala.collection.parallel.ParSeq 应该比 ListStream 处理 groupBy 更快,但前提是您有多个内核/超线程可用.但是,ParSeq 操作并不能保证保留按元素分组的顺序.

Also note that any type of Scala sequence will typically be processed sequentially (hence the name), by a single thread at a time. Neither List nor Stream lend themselves to parallel processing of their elements. If you need to process a collection in parallel, you'll need a parallel collection type (one of the collections in scala.collection.parallel). A scala.collection.parallel.ParSeq should process groupBy faster than a List or a Stream, but only if you have multiple cores/hyperthreads available. However, ParSeq operations do not guarantee to preserve the order of the grouped-by elements.

这篇关于Scala Stream vs Scala List vs Scala Sequence 有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆