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

时间:2018-02-18 09:44:29

标签: arrays swift performance reduce

考虑以下数组-of strings - :

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

为了组合它的元素(将“Hello”作为单个String),我们可以:

reduce it:

let reducedString = arrayStrings.reduce("", { $0 + $1 }) // "Hello"

join 它:

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

两者都会返回“Hello”字符串作为输出。

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

2 个答案:

答案 0 :(得分:7)

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

  1. 可读性

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

  2. 性能

    joined的{​​{1}}可以比String更好地实施。它不一定是,但它可以。 reduce一次操作一个元素,不知道其他元素,传递了许多临时变量。 reduce了解整个序列,并且知道操作始终相同,因此可以进行优化。它甚至可以使用joined的内部结构。请参阅String.joined implementation

  3. 总之,始终使用更具体的实现。 请注意,上述性能原因不太重要。

答案 1 :(得分:2)

更新之前的结果是通过在模拟器上运行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,该方法带有更多的语义值,它更好地传递意图。