Ответ 1
Отражатель показывает test2(), преобразованный в 4 класса, в то время как test1() превращается в два класса. Это происходит только в режиме отладки. Отражатель показывает идентичный код (по одному классу для каждого) в режиме деблокирования. К сожалению, рефлектор падает, когда я пытаюсь просмотреть исходный код на С#, а 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 64bit, 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