Вероятно, вы могли бы ускорить его, используя простую карту вместо compactMap. Вы не возвращаете необязательный (вроде), поэтому вам не нужно использовать compactMap. Фактически, ваше выражение d2[index] == value ? 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
из-за его удобочитаемости. Если производительность абсолютно критична, до такой степени, что вы решили, что можно пожертвовать читабельностью и удобством сопровождения ради крошечных прибавок к скорости, тогда, возможно, стоит переключиться на ручное индексирование, но это очень маловероятно. быть дело.
person
Alexander
schedule
02.03.2019
index
иelement
. Так что сортировать не надо... - person   schedule 02.03.2019compactMaping
для сравнения. Но для завершения цикла требуется 4 секунды. - person   schedule 02.03.2019map
вместоcompactMap
. Вы не возвращаете необязательный (вроде), поэтому вам не нужно использоватьcompactMap
. На самом деле, ваше выражениеd2[index] == value ? 0 : value
неявно повышается до необязательного только для того, чтобыcompactMap
потом пришлось тратить время на его распаковку. - person Alexander   schedule 02.03.2019