代码之家  ›  专栏  ›  技术社区  ›  Oleg Gordiichuk

Swift函数执行时间度量问题

  •  0
  • Oleg Gordiichuk  · 技术社区  · 6 年前

    extension Array where Element: Hashable {
        func uniqueOrderly() -> [Element] {
            let startTime = CFAbsoluteTimeGetCurrent()
            var set = Set<Element>()
            var array = [Element]()
            for element in self {
                if set.contains(element) {
                    continue
                }
                set.insert(element)
                array.append(element)
            }
            let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
            print("Time for uniqueOrderly: \(timeElapsed)")
            return array
        }
    }
    

    第二点:

    public extension Sequence where Element: Equatable {
        func unique() -> [Element] {
            let startTime = CFAbsoluteTimeGetCurrent()
            var unique: [Element] {
                return reduce(into: []) {
                    unique, x in
                    if !unique.contains(x) {
                        unique.append(x)
                    }
                }
            }
            let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
            print("Time for unique: \(timeElapsed)")
            return unique
        }
    }
    

    即:

    let arrayToFilter = [1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1]
    

    arrayToFilter.unique() //Time for unique: 0.00012195110321044922
    arrayToFilter.uniqueOrderly() Time for uniqueOrderly: 0.02329099178314209
    

    但当我改变函数调用的顺序时 unique() 函数显示可怕的时间测量。

    arrayToFilter.uniqueOrderly() //Time for uniqueOrderly: 0.0013059377670288086
    arrayToFilter.unique() //Time for unique: 8.940696716308594e-06
    

    所以我的问题是,为什么在不同的函数调用顺序下会出现这种情况?另外,当我在for循环中运行这些测试时,测量结果是完全不同的(大约+-1秒)

    所有的mesurants都是在操场和真实的iOS应用程序中完成的,带有发布构建设置(在模拟器上)。

    测试规格:

    Swift 4.2

    1 回复  |  直到 6 年前
        1
  •  2
  •   Rob Napier    6 年前

    你的 unique() 实现在计算之前计算经过的时间 unique . 独特的 是计算的var,在访问时进行评估。

    uniqueOrderly() 实施仍将比预期缓慢 唯一的()

    至于排序问题,这几乎可以肯定是您如何测试它的一个产物。微观分析非常具有挑战性。我把每一个都放进自己的电脑里进行测试 .swift swift -O <file> 实际上,为了给它的活动计时,当运行时,时间是相当一致的 :

    Time for uniqueOrderly: 1.800060272216797e-05
    [1, 2, 4, 6, 5, 7, 9, 3]
    Time for unique: 2.0265579223632812e-06
    [1, 2, 4, 6, 5, 7, 9, 3]
    
    Time for unique: 2.002716064453125e-05
    [1, 2, 4, 6, 5, 7, 9, 3]
    Time for uniqueOrderly: 2.9802322387695312e-06
    [1, 2, 4, 6, 5, 7, 9, 3]
    

    无论如何,这种微观优化是没有意义的。你要整天追鬼。很难在微小的数据块上测试微小的代码片段,并以适用于实际使用的方式对其进行优化。至少,您需要非常大的阵列,并在许多不同类型的发行版上进行测试(大量的重复版本而很少)。您必须在操场外进行测试,并且必须使用优化器。