【发布时间】:2012-05-04 18:22:41
【问题描述】:
这样的功能存在吗?类似 Java HotSpot 的东西在服务器模式下运行,但用于 .Net 应用程序。
编辑: 更多信息。我有一个小应用程序(用 F# 编写),里面有很多小功能。喜欢这个:
let printable b =
if b >= ' 'B && b <= '~'B
then b else '.'B
我意识到性能很差,在分析后我看到每个这样的函数都被调用了数百万次。我制作了它们inline 并获得了性能提升(5 倍以上,可能更多)。
好的,很好。现在性能很好。但是为什么框架不这样做呢?它有足够的关于我的代码和函数被调用频率的信息。为什么不内联一个被调用了 1M 次的函数?
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,则没有时间差异。
因此,“小功能”和优化没有任何问题。
【问题讨论】:
-
是的,这就是 CLR 的 JIT 所做的。
-
@HansPassantI 我添加了更多信息,问题与调试/发布模式无关。
-
问题的标题歪曲了实际问题。对标题的有效回答是“是的,.net 在运行时做了 一些 优化”。这实际上不会回答你的问题。也许您应该改写为“Microsoft 的 .net CLR 是否在运行时内联小函数?”
-
@Mystere : server HotSpot 确实基于“热”代码路径(因此命名)进行自适应运行时优化,即更频繁执行的代码路径或分支可以使用不同或更激进的优化重新 JIT 编译。
标签: .net optimization f#