【问题标题】:Why `joined()` is much slower than `flatMap()`? [duplicate]为什么`joined()` 比`flatMap()` 慢得多? [复制]
【发布时间】:2021-07-03 04:06:43
【问题描述】:

我想用joined()加入一个大数组,我发现这个方法很慢,比flatMap()慢很多,这里是重现它的代码。

如你所见,joined 大约需要 0.26s,flatMap 大约需要 0.0064s,你知道为什么会这样吗?

import Foundation

var datas = [Data]()
var count = 0
(0...10000).forEach { _ in
    let data = """
            public struct FlattenSequence<Base: Sequence> where Base.Element: Sequence {
            public struct FlattenSequence<Base: Sequence> where Base.Element: Sequence {
            """.data(using: .utf8)!
    datas.append(data)
    count += data.count
}



// 1st approach, it takes 0.0049s, around 40 times faster than the 2nd approach.
let start1 = Date()
var wholeData1 = Data(capacity: count)
datas.forEach {
    wholeData1.append($0)
}
print("Time 1: \(Date().timeIntervalSince(start1))")

// 2nd approach, it takes 0.26s,
let start2 = Date()
let wholeData2 = Data.init(datas.joined())
print("Time 2: \(Date().timeIntervalSince(start2))")

// 3rd approach, it takes 0.0064s
let start3 = Date()
let wholeData3 = Data.init(datas.flatMap { $0 })
print("Time 3: \(Date().timeIntervalSince(start3))")

print(wholeData1 == wholeData2)
print(wholeData1 == wholeData3)
print(count)

【问题讨论】:

标签: swift


【解决方案1】:

读完这篇文档

/// The `joined` method is always lazy, but does not implicitly
/// confer laziness on algorithms applied to its result.  In other
/// words, for ordinary sequences `s`:
///
/// * `s.joined()` does not create new storage
/// * `s.joined().map(f)` maps eagerly and returns a new array
/// * `s.lazy.joined().map(f)` maps lazily and return

我又做了一些测试,发现datas.lazy.flatMap { $0 }datas.lazy.joined()datas.joined()的性能非常相似,这意味着慢是懒惰造成的。

但我还是不明白为什么swift决定让joined方法总是惰性的,我们已经有了LazySequence,我们总是可以通过array.lazy.method来惰性调用数组方法。

恕我直言,更好的选择是消除 joined 的懒惰,我们仍然可以通过 array.lazy.joined() 懒惰地调用它。

【讨论】:

    猜你喜欢
    • 2015-10-11
    • 2011-04-29
    • 1970-01-01
    • 2017-12-26
    • 2011-01-25
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 2017-05-10
    相关资源
    最近更新 更多