如何使用整个模块优化来测试通用性能

Dan*_*ieu 6 generics optimization compiler-optimization swift

在WWDC 2015 Session 409附近的18分钟标记.手头的讨论让我相信,通过启用整个模块优化模式,可以通过Generic Specialization优化泛型.不幸的是,我对自己没有信心的测试显示没什么用处.

我在以下两种方法之间运行了一些非常简单的测试,以查看性能是否相似:

func genericMax<T : Comparable>(x:T, y:T) -> T {
    return y > x ? y : x
}

func intMax(x:Int, y:Int) -> Int {
    return y > x ? y : x
}
Run Code Online (Sandbox Code Playgroud)

简单的XCTest:

func testPerformanceExample() {

    self.measureBlock {

        let x: Int = Int(arc4random_uniform(9999))
        let y: Int = Int(arc4random_uniform(9999))

        for _ in 0...1000000 {
            // let _ = genericMax(x, y: y)
            let _ = intMax(x, y: y)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

发生了什么

如果没有优化,以下测试会有相当不同:

  • genericMax:0.018秒
  • intMax:0.005秒

但是,对于整个模块优化,以下测试不相似:

  • genericMax:0.014秒
  • intMax:0.004秒

我所期待的

启用整个模块优化后,我预计两个方法调用之间的时间相似.这让我相信我的测试是有缺陷的.

假设我的测试有缺陷/差.我怎样才能更好地衡量整体模块优化模式如何通过通用专业化来优化泛型?

zne*_*eak 3

您的测试存在缺陷,因为它们衡量的是测试性能,而不是应用程序性能。测试位于单独的可执行文件中,它们本身并不能从整个模块优化中受益。因此,即使在程序不使用的地方,您的测试也始终使用通用的非专用实现。

如果您想查看可执行文件中启用了全模块优化,则需要测试可执行文件中的函数。(您还需要确保您的测试使用发布版本,或者在调试版本中启用了 WMO。)

将此函数添加到可执行文件中:

func genericIntMax(x: Int, y: Int) -> Int {
    return genericMax(x, y: y)
}
Run Code Online (Sandbox Code Playgroud)

并在测试中使用它来代替genericMax测试中,我得到了相同的性能。(请注意,这并不是真正的整个模块优化,因为这两个函数位于同一文件中;但它显示了在优化方面应用程序代码和测试代码之间的差异。)