【发布时间】:2016-11-24 14:34:45
【问题描述】:
import XCTest
class testTests: XCTestCase {
static func makearray() -> [Int] {
var array: [Int] = []
for x in 0..<1000000 {
array.append(x)
}
return array
}
let array = testTests.makearray()
func testPerformanceExample() {
self.measure {
var result: [String] = []
for x in self.array {
let tmp = "string\(x)"
if tmp.hasSuffix("1234") {
result.append(tmp)
}
}
print(result.count)
}
}
func testPerformanceExample2() {
self.measure {
let result = self.array.map { "string\($0)" }
.filter { $0.hasSuffix("1234") }
print(result.count)
}
}
func testPerformanceExample3() {
self.measure {
let result = self.array.flatMap { int -> String? in
let tmp = "string\(int)"
return tmp.hasSuffix("1234") ? tmp : nil
}
print(result.count)
}
}
}
在这段代码中,我试图了解高阶函数在处理大型数组方面的表现。
3 次测试产生相同的结果,循环时间约为 0.75 秒,地图/过滤器时间为 1.38 秒,平面地图时间为 1.21 秒。
假设 HOF 或多或少是包装循环的函数,这在 map/filter 的情况下是有意义的,它循环遍历 map 的第一个数组,然后循环遍历其结果以进行过滤。
在flatmap的情况下,是不是先做map,再做更简单的filter操作?
我对幕后发生的事情的理解(大致)正确吗?
如果是这样,是否可以说编译器无法对此进行太多优化?
最后,有没有更好的方法来做到这一点? HOF 版本对我来说肯定更容易理解,但对于性能关键领域,看起来 for-loops 是要走的路?
【问题讨论】:
-
您是否真的遇到过这很重要的情况,或者这只是理论上的情况?
-
此外,如果性能真的很关键,那么您肯定会直接写入内存。所以我很难相信这绝不是浪费时间。
-
你真的告诉编译器进行优化吗?如果没有,这一切都毫无意义,不是吗?
-
你可以在github.com/apple/swift/blob/master/stdlib/public/core/…找到flatMap的源代码,它是单通道的,不是map+filter。 – 如果 map 明显慢于等效的显式循环(在优化代码中),那么您可能需要提交错误报告。
-
抱歉,马特,但我不确定你在说什么?我确实有需要处理大量数据的情况。
标签: swift performance functional-programming