Swift 4.2中的快速阵列比较

Swift 4.2中的快速阵列比较,swift,swift4.2,Swift,Swift4.2,我有两个整数数组,有11059200个元素。从下面的例子中 我正在通过比较d2中元素的索引,将数组d1的值更改为0 以下程序的计算时间为 Comparing started: 2019-03-02 08:45:56 +0000 Comparing finished: 2019-03-02 08:46:00 +0000 这个过程花了4秒,时间更长 我想减少时间。有什么可能性吗?多谢各位 var d1 = [Int]() var d2 = [Int]() let value = 11059200

我有两个整数数组,有11059200个元素。从下面的例子中

我正在通过比较
d2中元素的索引,将数组
d1
的值更改为0

以下程序的计算时间为

Comparing started: 2019-03-02 08:45:56 +0000
Comparing finished: 2019-03-02 08:46:00 +0000

这个过程花了4秒,时间更长

我想减少时间。有什么可能性吗?多谢各位

var d1 = [Int]()
var d2 = [Int]()

let value = 11059200

for _ in 0...value{

    d1.append(Int.random(in: 0...value))
    d2.append(Int.random(in: 0...value))
}

print("Comparing started: \(Date())")

var _ = d1.enumerated().compactMap { (index,value) -> Int in

    return d2[index] == value ? 0 : value
}

print("Comparing finished: \(Date())")
更新:

根据Alexander的评论,我正在使用map将时间从2-3秒缩短

var _ = d1.enumerated().map { (index,value) -> Int in
  return d2[index] == value ? 0 : value
}

您可能可以使用简单的贴图而不是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)
}
<代码>导入基础 func PrintTimeElapsedWhenRunning代码(标题:字符串,操作:()->Void){ 让startTime=CFAbsoluteTimeGetCurrent() 操作() 让时间流逝=CFAbsoluteTimeGetCurrent()-startTime 打印(“已用时间\(标题):\(已用时间)s.) } 设max=11059200 设d1=(0…max).map{in Int.random(in:0…max)} 设d2=(0…max).map{in Int.random(in:0…max)} PrintTimeElapsedWhenRunning代码(标题:“枚举和索引,使用compactMap进行比较(原始)”){ 让result=d1.enumerated().compactMap{index,value->Int in 返回d2[索引]==值?0:值 } 打印(结果计数) } PrintTimeElapsedWhenRunning代码(标题:“枚举和索引,使用映射进行比较”){ 让result=d1.enumerated().map{index,value->Int in 返回d2[索引]==值?0:值 } 打印(结果计数) } //仅作为基准,不要像这样编写代码。 运行代码时的打印时间延迟(标题:“手动索引”){ var result=Array() 结果.储备容量(d1.计数) 对于d1.1中的i{ 设(d1Value,d2Value)=(d1[i],d2[i]) 让newValue=d1Value==d2Value?0:d1Value result.append(newValue) } 打印(结果计数) } //从可读性角度看“最佳” 运行代码时的打印时间延迟(标题:“Zip”){ 让result=zip(d1,d2).map{d1Value,d2Value in 返回d1Value==d2Value?0:d1Value } 打印(结果计数) }
以下是未优化构建中的初步结果。这些都是毫无意义的。调试构建的目标是让编译器在尽可能短的时间内生成一个正确的、可运行的程序,并且绝对不关注性能。这对于快速开发迭代来说是很好的,但是对于基准测试来说是无用的

使用compactMap(原始)比较枚举和索引所用的时间:6.206556916236877 s

手动索引所用时间:0.3380240201950073秒

压缩时间:7.123739957809448秒

枚举和索引所用的时间,使用映射进行比较:5.2529460191726685 s

当您启用优化(swiftccli中的
-O
标志,或者作为Xcode构建目标中的一个选项)时,您会看到完全不同的画面:

使用compactMap(原始)比较枚举和索引所用的时间:0.590499043466606 s

枚举和索引所用的时间,使用映射进行比较:0.22207605838775635 s

手动索引所用时间:0.18644499778747559秒

压缩时间:0.2339940071105957秒


我建议使用基于
zip
的方法,以提高可读性。如果性能是绝对关键的,以至于你已经决定牺牲可读性和可维护性来换取微小的速度优势是可以的,那么切换到手动索引可能是值得的,但这种情况不太可能发生。

会让它们按更快的速度排序吗?@MadProgrammer,我需要
索引
元素
。所以,它不应该被排序…“这个过程花了4秒,时间更长。”???您正在丢弃整个操作的结果。“那你到底想做什么呢?”亚历山大,整个行动的结果对我来说很重要。我正在努力缩短映射时间。我不知道我需要用什么。因此,我使用
compactMaping
进行比较。但是完成循环需要4秒钟。