Возможно, вы могли бы ускорить его, используя простую карту вместо CompactMap.Вы не возвращаете Optional (вроде), поэтому вам не нужно использовать compactMap.На самом деле ваше выражение d2 [index] == значение?0: значение неявно повышается до необязательного, только для compactMap, чтобы затем тратить время на его развертывание.
Кроме того, вы можете упростить код, используя zip
для итерации двух последовательностей:
import Foundation
func printTimeElapsedWhenRunningCode(title: String, operation: () -> Void) {
let startTime = CFAbsoluteTimeGetCurrent()
operation()
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("Time elapsed for \(title): \(timeElapsed) s.")
}
let max = 11059200
let d1 = (0...max).map { _ in Int.random(in: 0...max) }
let d2 = (0...max).map { _ in Int.random(in: 0...max) }
printTimeElapsedWhenRunningCode(title: "Enumerating and indexing, comparing using compactMap (original)") {
let result = d1.enumerated().compactMap { index, value -> Int in
return d2[index] == value ? 0 : value
}
print(result.count)
}
printTimeElapsedWhenRunningCode(title: "Enumerating and indexing, comparing using map") {
let result = d1.enumerated().map { index, value -> Int in
return d2[index] == value ? 0 : value
}
print(result.count)
}
// just for a benchmark, don't write codel like this.
printTimeElapsedWhenRunningCode(title: "Manual Indexing") {
var result = Array<Int>()
result.reserveCapacity(d1.count)
for i in d1.indices {
let (d1Value, d2Value) = (d1[i], d2[i])
let newValue = d1Value == d2Value ? 0 : d1Value
result.append(newValue)
}
print(result.count)
}
// "Best" from a readibility stand-point
printTimeElapsedWhenRunningCode(title: "Zip") {
let result = zip(d1, d2).map { d1Value, d2Value in
return d1Value == d2Value ? 0 : d1Value
}
print(result.count)
}
Вот предварительные результаты в неоптимизированной сборке.Это абсолютно бессмысленно .Цель отладочных сборок состоит в том, чтобы компилятор создал правильную работоспособную программу в кратчайшие сроки с абсолютно нулевым вниманием к производительности.Он отлично подходит для быстрой итерации разработки, но бесполезен для бенчмаркинга.
Время, затраченное на перечисление и индексирование, сравнение с использованием compactMap (оригинал): 6.206556916236877 с.
Время, потраченное на ручное управлениеИндексирование: 0,3380240201950073 с.
Время, прошедшее для Zip: 7.123739957809448 с.
Время, прошедшее для перечисления и индексации, сравнение с использованием карты: 5.2529460191726685 с.
Когда вывключив оптимизацию (флаг -O
в swiftc
cli или в качестве опции в вашей цели сборки Xcode), вы получите совершенно другую картину:
Время, прошедшее для перечисления и индексации,сравнение с использованием compactMap (оригинал): 0,5904990434646606 с.
Время, затраченное на перечисление и индексирование, сравнение с использованием карты: 0,22207605838775635 с.
Время, потраченное на ручное индексирование: 0,18644499778747559 с.
* Прошедшее время для Zip: 0,2339940071105957 с.
Я бы порекомендовал подход на основе zip
ч за его читабельность.Если производительность абсолютно критически важна, до того момента, когда вы определили, что можно жертвовать удобочитаемостью и удобством обслуживания для крошечных перков скорости, тогда, возможно, стоит переключиться на ручную индексацию, но это вряд ли будетдело.