代码之家  ›  专栏  ›  技术社区  ›  Dan Beaulieu

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

  •  6
  • Dan Beaulieu  · 技术社区  · 10 年前

    在WWDC 2015第409期比赛中,接近18分钟的大关。手边的讨论让我相信,通过启用整个模块优化模式,泛型可以通过泛型专业化进行优化。不幸的是,我的测试(我对此不太自信)没有发现任何有用的东西。

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

    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
    }
    

    简单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)
            }
        }
    }
    

    怎么搞的?

    在没有优化的情况下,以下测试是合理不同的:

    • 一般最大值:0.018秒
    • int最大值:0.005秒

    然而,对于整个模块优化,以下测试并不相似:

    • 一般最大值:0.014秒
    • int最大值:0.004秒

    我的期望

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

    问题

    假设我的测试有缺陷/差。我如何更好地衡量整个模块优化模式如何通过泛型专业化优化泛型?

    1 回复  |  直到 10 年前
        1
  •  3
  •   zneak    10 年前

    你的测试有缺陷,因为它们衡量的是测试性能,而不是应用程序性能。测试存在于一个单独的可执行文件中,它们本身无法从整个模块优化中获益。因此,即使在程序没有的地方,您的测试也总是使用通用的、非专用的实现。

    如果您希望看到在可执行文件中启用了整个模块优化,则需要从可执行文件测试一个函数。(您还需要确保测试使用发布版本,或者在调试版本中启用了WMO。)

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

    func genericIntMax(x: Int, y: Int) -> Int {
        return genericMax(x, y: y)
    }
    

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