Uczę się F # i jedną rzeczą, która mnie interesuje w tym języku, jest wydajność. Napisałem mały test porównawczy, w którym porównuję idiomatyczny F # z imperatywnym kodem napisanym w tym samym języku - i ku mojemu zaskoczeniu funkcjonalna wersja wychodzi znacznie szybciej.Seq.map jest szybszy niż zwykła pętla?
Benchmark składa się z:
- Reading w pliku tekstowym za pomocą File.ReadAllLines
- odwrócenie kolejności znaków w ramach danej linii
- odpisaniu wynik do tego samego pliku przy użyciu File.WriteAllLines .
Oto kod:
open System
open System.IO
open System.Diagnostics
let reverseString(str:string) =
new string(Array.rev(str.ToCharArray()))
let CSharpStyle() =
let lines = File.ReadAllLines("text.txt")
for i in 0 .. lines.Length - 1 do
lines.[i] <- reverseString(lines.[i])
File.WriteAllLines("text.txt", lines)
let FSharpStyle() =
File.ReadAllLines("text.txt")
|> Seq.map reverseString
|> (fun lines -> File.WriteAllLines("text.txt", lines))
let benchmark func message =
// initial call for warm-up
func()
let sw = Stopwatch.StartNew()
for i in 0 .. 19 do
func()
printfn message sw.ElapsedMilliseconds
[<EntryPoint>]
let main args =
benchmark CSharpStyle "C# time: %d ms"
benchmark FSharpStyle "F# time: %d ms"
0
Niezależnie od wielkości pliku, "F # -Style" wersja uzupełnia w około 75% czasu w "C# -Style" wersji. Moje pytanie brzmi: dlaczego tak jest? Nie widzę oczywistej nieskuteczności w imperatywnej wersji.
Kudos @Dr_Asik za dobrze przygotowane pytanie. –