使用 reduce 或 joined 组合数组有什么区别?

What is the difference between combining array by using reduce or joined?

考虑以下字符串数组:

let arrayStrings = ["H", "e", "l", "l", "o"]

为了组合其元素(将 "Hello" 作为单个字符串),我们可以:

reduce它:

let reducedString = arrayStrings.reduce("", { [=11=] +  }) // "Hello"

或者join它:

let joinedString = arrayStrings.joined() // "Hello"

两者都会 return "Hello" 字符串作为输出。

但是,在确定这种过程的更好选择时要牢记什么逻辑?根据性能进行比较时有什么区别?

joinedreduce 更好的选择有两个原因:

  1. 可读性

    如果要将多个字符串连接成一个字符串,为什么要使用 reduce 并进行手动连接?如果您要执行的任务有特定功能,请使用它。阅读代码时,joinedreduce.

  2. 更容易理解
  3. 性能

    joined 对于 String 的实现比 reduce 更好。它不一定是,但它可以。 reduce 一次对一个元素进行操作,不知道其他元素,并传递许多临时变量。 joined 知道整个序列,它知道操作总是相同的,因此它可以优化。它甚至可以使用String的内部结构。见 String.joined implementation.

总而言之,始终使用更具体的实现。 请注意,上面的性能原因是次要的。

更新 之前的结果是在模拟器上运行ning一个iOS应用得到的。 运行 真实设备上的应用程序,或 运行 从 MacOS 命令行应用程序中调用代码给出与@Sulthan 提到的相似的结果。


有趣的是,reduce 在我的机器上得到了更好的结果:

func benchmark(_ label: String, times: Int = 100000, _ f: () -> Void) {
    let start = CACurrentMediaTime()
    (0..<times).forEach { _ in f() }
    let end = CACurrentMediaTime()
    print("\(label) took \(end-start)")
}

let arrayStrings = ["H", "e", "l", "l", "o"]
benchmark("reduce", { _ = arrayStrings.reduce("", +) } )
benchmark("join", { _ = arrayStrings.joined() })

当 运行 来自典型 iOS 应用程序的 main 方法时,在调试模式下构建时,结果约为以下数字:

reduce took 0.358474982960615
join took 0.582276367989834

在发布模式下构建的同一应用给出了相同的结果顺序:

reduce took 0.126910287013743
join took 0.0291724550188519

我多次 运行 基准测试,reduce 在所有情况下都表现更好。不过区别并不大,所以除非你的字符串操作对性能至关重要,否则我建议使用 joined,该方法具有更多的语义价值,它更好地表达了意图 运行。