gpt4 book ai didi

Scala:读取并保存 Iterable 的所有元素

转载 作者:行者123 更新时间:2023-12-03 21:24:26 25 4
gpt4 key购买 nike

我有一个 Iterable[T],它实际上是一个未知长度的流,我想读取所有内容并将其保存到仍然是 Iterable 实例的内容中。我真的必须阅读并保存它;我不能以懒惰的方式做到这一点。原始的 Iterable 至少可以有几千个元素。最有效/最好/最规范的方式是什么?我应该使用 ArrayBuffer、List 还是 Vector?

假设 xs 是我的 Iterable。我可以想到做这些可能性:

xs.toArray.toIterable     // Ugh?
xs.toList // Fast?
xs.copyToBuffer(anArrayBuffer)
Vector(xs: _*) // There's no toVector, sadly. Is this construct as efficient?

编辑:我看到我应该更具体的问题。这是一个稻草人的例子:
def f(xs: Iterable[SomeType]) {    // xs might a stream, though I can't be sure
val allOfXS = <xs all read in at once>
g(allOfXS)
h(allOfXS) // Both g() and h() take an Iterable[SomeType]
}

最佳答案

这很简单。几千个元素不算什么,所以除非它是一个非常紧密的循环,否则它几乎不重要。所以轻率的答案是:使用你觉得最优雅的任何东西。

但是,好吧,让我们假设这实际上是在某个紧密循环中,并且您可以预测或对代码进行足够的基准测试,以知道这会限制性能。

不可变解决方案的最佳性能可能是 Vector ,像这样使用:

Vector() ++ xs

在我的手中,这可以复制 10k 迭代大约每秒 4k-5k 次。 List大约是速度的一半。

如果你愿意在幕后尝试一个可变的解决方案, xs.toArray.toIterable通常以每秒约 10k 份的速度获取蛋糕。 ArrayBufferList 的速度大致相同.

如果你真的知道目标的大小(即 sizeO(1) 或者你从其他地方知道),你可以通过分配正确的大小并写入一段时间来再削减 20-30% 的执行速度环形。

如果它实际上是基元,则可以通过编写自己的专用 Iterable 获得 10 倍的因数。 -like-thing 作用于数组并通过底层数组转换为常规集合。

底线:要实现强大的功能、速度和灵活性,请使用 Vector() ++ xs在大多数情况下。 xs.toIndexedSeq默认为相同的东西,好处是如果它已经是 Vector它根本不需要时间(并且在不使用括号的情况下很好地链接),以及您依赖约定而不是行为规范的缺点(并且需要输入 1-3 个字符)。

关于Scala:读取并保存 Iterable 的所有元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6782346/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com