gpt4 book ai didi

F# 性能问题 : what is the compiler doing?

转载 作者:行者123 更新时间:2023-12-05 01:36:01 25 4
gpt4 key购买 nike

引用此代码:F# Static Member Type Constraints

为什么是,例如,

let gL = G_of 1L
[1L..100000L] |> List.map (fun n -> factorize gL n)

明显慢于
[1L..100000L] |> List.map (fun n -> factorize (G_of 1L) n)

通过查看 Reflector,我可以看到编译器正在以非常不同的方式处理每一个,但是有太多的事情让我无法破译本质区别。我天真地认为前者会比后者表现得更好,因为 gL 是预先计算的,而 G_of 1L 必须计算 100,000 次(至少看起来是这样)。

[ 编辑 ]

看起来这可能是 F# 2.0/.NET 2.0/Release-mode 的错误,请参阅 @gradbot 的回答和讨论。

最佳答案

反射器显示 test2() 变成了 4 个类,而 test1() 变成了两个类。这仅在 Debug模式下发生。 Reflector 在 Release模式下显示相同的代码(每个类一个)。不幸的是,当我尝试在 C# 中查看源代码时,Reflector 崩溃了,并且 IL 非常长。

let test1() =
let gL = G_of 1L
[1L..1000000L] |> List.map (fun n -> factorize gL n)

let test2() =
[1L..1000000L] |> List.map (fun n -> factorize (G_of 1L) n)

一个快速的基准。
let sw = Stopwatch.StartNew()
test1() |> ignore
sw.Stop()
Console.WriteLine("test1 {0}ms", sw.ElapsedMilliseconds)

let sw2 = Stopwatch.StartNew()
test2() |> ignore
sw2.Stop()
Console.WriteLine("test2 {0}ms", sw2.ElapsedMilliseconds)

基准测试在 I7 950 @3368Mhz、Windows 7 64 位、VS2010 F#2.0 上运行

x86 调试 test1 8216ms test2 8237ms
x86 发布 test1 6654ms test2 6680ms
x64 调试 test1 10304ms test2 10348ms
x64 版本 test1 8858ms test2 8977ms
这是完整的代码。
open System
open System.Diagnostics

let inline zero_of (target:'a) : 'a = LanguagePrimitives.GenericZero<'a>
let inline one_of (target:'a) : 'a = LanguagePrimitives.GenericOne<'a>
let inline two_of (target:'a) : 'a = one_of(target) + one_of(target)
let inline three_of (target:'a) : 'a = two_of(target) + one_of(target)
let inline negone_of (target:'a) : 'a = zero_of(target) - one_of(target)

let inline any_of (target:'a) (x:int) : 'a =
let one:'a = one_of target
let zero:'a = zero_of target
let xu = if x > 0 then 1 else -1
let gu:'a = if x > 0 then one else zero-one

let rec get i g =
if i = x then g
else get (i+xu) (g+gu)
get 0 zero

type G<'a> = {
negone:'a
zero:'a
one:'a
two:'a
three:'a
any: int -> 'a
}

let inline G_of (target:'a) : (G<'a>) = {
zero = zero_of target
one = one_of target
two = two_of target
three = three_of target
negone = negone_of target
any = any_of target
}

let inline factorizeG n =
let g = G_of n
let rec factorize n j flist =
if n = g.one then flist
elif n % j = g.zero then factorize (n/j) j (j::flist)
else factorize n (j + g.one) (flist)
factorize n g.two []

let inline factorize (g:G<'a>) n = //'
let rec factorize n j flist =
if n = g.one then flist
elif n % j = g.zero then factorize (n/j) j (j::flist)
else factorize n (j + g.one) (flist)
factorize n g.two []

let test1() =
let gL = G_of 1L
[1L..100000L] |> List.map (fun n -> factorize gL n)

let test2() =
[1L..100000L] |> List.map (fun n -> factorize (G_of 1L) n)

let sw2 = Stopwatch.StartNew()
test1() |> ignore
sw2.Stop()
Console.WriteLine("test1 {0}ms", sw2.ElapsedMilliseconds)

let sw = Stopwatch.StartNew()
test2() |> ignore
sw.Stop()
Console.WriteLine("test2 {0}ms", sw.ElapsedMilliseconds)

Console.ReadLine() |> ignore

关于F# 性能问题 : what is the compiler doing?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2945880/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com