这样的特征是否存在?类似于在服务器模式下运行的Java HotSpot,但适用于.Net应用程序。
编辑:更多信息。我有小应用程序(用F#编写),其中有很多小函数。就像这个:
let printable b =
    if b >= ' 'B && b <= '~'B
    then b else '.'B我已经意识到了这种糟糕的性能,在分析之后,我发现每个这样的函数都被调用了数百万次。我做了inline,并获得了性能提升(5+时间,可能会更多)。
好的,很好。现在的表现很好。但是为什么框架不去做呢?它有足够的关于我的代码和函数被调用的频率的信息。为什么它不内联一个称为100万次的函数?
EDIT2:测量内联函数差异的示例测试:
    open System
    let printableByte b =
        if b >= ' 'B && b <= '~'B
        then b else '.'B
    let foo (arr : byte[]) = 
        for i in 0..arr.Length-1 do
            arr.[i] <- printableByte (arr.[i])
        arr.Length / 1000
    let main() =
        let sum = ref 0
        let arr = Array.create 1000000 0uy
        let stopWatch = System.Diagnostics.Stopwatch()
        stopWatch.Start()
        for x in 0..5000 do
            sum := !sum + (foo arr)
        stopWatch.Stop()
        printfn "%d" !sum 
        printfn "total time = %A" stopWatch.ElapsedMilliseconds
        ()
    main()当printableByte没有内联时,它运行19.5秒,内联时运行13.6秒。
EDIT3:只有为x86目标编译并在x64主机上运行时,才能查看此时间差。如果编译为"anycpu“或x64,则没有时间差。
因此,“小函数”和优化没有任何问题。
发布于 2012-05-04 19:13:59
是的,CLR做了一些运行时优化,如这个博客所示。请注意,根据这篇文章,虚拟方法不是内联的。
这两种方法都没有内联:
您的printable函数是如何在代码中调用的?如果F#编译器将它封装在一个闭包中,它通常会这样做,即使在您一开始可能不期望它的情况下,您也会陷入“虚拟方法”的情况。
发布于 2012-05-04 21:20:20
请记住,在FSI中测试此代码与在Release模式下编译项目是不一样的。
我的高度非科学测试表明,如果将Debug添加到printableByte中,您提供的性能测试在printableByte中运行得更好。
但是,当inline被添加到Release模式时,程序的性能实际上比没有它更差。我相信F#编译器团队或一些反汇编会告诉你为什么.
在我使用F#的经验中,您应该很少需要手动应用内联优化。只需确保您在Release中编译即可!
编辑:啊哈,是的!确保在“任意CPU”模式下编译,除非您有特定的原因不编译(通常我的原因是必须从x86 COM库从F#进行互操作)。
发布于 2012-05-04 18:24:38
是的,.net框架优化了它正在运行的平台的代码。它考虑了许多因素。但也有一些事情是做不到的.例如,我不认为它使用SIMD指令,如果它们是可用的。但总的来说,它确实做得很好。
https://stackoverflow.com/questions/10454160
复制相似问题