2016-03-11 57 views
1

我想查看List.toArray和Seq.toArray之間是否存在任何性能差異,所以我寫了一個小腳本。我多次運行各種測試。我編譯了這個版本模式。將列表轉換爲數組反覆出現偶爾下降

open System.Diagnostics 

let n = 5000000 

let biglist = [1.0 .. float(n)] 

let SeqTest input = 
    input |> Seq.toArray 

let ListTest input = 
    input |> List.toArray 

let timeIt (name : string) (f : float list -> 'T) : unit = 
    let sw = Stopwatch() 
    sw.Start() 
    f biglist |> ignore 
    let d = sw.ElapsedMilliseconds 
    printfn "%s, elapsed %d ms" name d 

[<EntryPoint>] 
let main argv = 
    timeIt "SeqTest" SeqTest 
    timeIt "ListTest" ListTest 

    timeIt "ListTest" ListTest 
    timeIt "SeqTest" SeqTest 

    timeIt "SeqTest" SeqTest 
    timeIt "ListTest" ListTest 

    timeIt "ListTest" ListTest 
    timeIt "SeqTest" SeqTest 

    timeIt "SeqTest" SeqTest 
    timeIt "ListTest" ListTest 
    0 

這是我得到了什麼,當我跑的程序:

ListTest, elapsed 27 ms 
SeqTest, elapsed 26 ms 
SeqTest, elapsed 136 ms 
ListTest, elapsed 27 ms 
ListTest, elapsed 135 ms 
SeqTest, elapsed 26 ms 
SeqTest, elapsed 136 ms 
ListTest, elapsed 26 ms 
ListTest, elapsed 138 ms 
SeqTest, elapsed 29 ms 

我注意到,第三測試花費的時間比以前的2次測試,並且是第3次試驗後,所有其他的測試需要同樣長跑步。爲什麼會發生?

編輯:來自Gilles的評論似乎表明,這是因爲垃圾收集。有什麼辦法讓我展示這個嗎?

+6

GC是首先想到的。嘗試在測試中添加GC跟蹤(我不知道如何在F#中執行此操作)。 – Gilles

回答

0

感謝@Gilles的提示,我能夠確定這是垃圾收集器放慢了我的速度。當我在每次計時測試後強制垃圾收集器以System.GC.Collect()運行時,我的測試結果給出了一致的時間。

+0

您也可以(另外)嘗試使用https://msdn.microsoft.com/en-us/library/system.gc.trystartnogcregion.aspx和https://msdn.microsoft.com/en-us/library/ system.gc.endnogcregion.aspx(在.NET 4.6中可用)使用這些可以確保在計時期間不會發生GC開銷。顯然你也應該分析生產代碼,包括GC。 – CaringDev