迭代時給堆棧溢出我有以下結構的CSV文件:爲什麼SEQ通過大csv文件
- 第一行是頭行
- 剩餘線是數據線,每一 與相同數量的逗號,所以我們可以在列 方面認爲數據的
我已經寫了一個小腳本去通過文件的每一行,並返回一個包含列標題元組序列和日數據該列中的最大的字符串電子長度:
let getColumnInfo (fileName:string) =
let delimiter = ','
let readLinesIntoColumns (sr:StreamReader) = seq {
while not sr.EndOfStream do
yield sr.ReadLine().Split(delimiter) |> Seq.map (fun c -> c.Length)
}
use sr = new StreamReader(fileName)
let headers = sr.ReadLine().Split(delimiter)
let columnSizes =
let initial = Seq.map (fun h -> 0) headers
let toMaxColLengths (accumulator:seq<int>) (line:seq<int>) =
let chooseBigger a b = if a > b then a else b
Seq.map2 chooseBigger accumulator line
readLinesIntoColumns sr |> Seq.fold toMaxColLengths initial
Seq.zip headers columnSizes;
這對一個小文件工作正常。然而,當它試圖處理一個大文件(> 75 Mb)時,會出現StackOverflow異常。如果我刪除線
Seq.map2 chooseBigger accumulator line
該程序完成。
現在,我的問題是這樣的:爲什麼F#使用堆棧?我對F#中序列的理解是,整個序列不保存在內存中,只保留正在處理的元素。因此,我預計已經處理過的行將不會保留在堆棧上。我的誤解在哪裏?
75Mb文件中有多少行和列? – pad 2012-03-09 15:30:35
我不知道。至少50,000。這並不是我想讓它發揮作用,我更加好奇爲什麼我對F#的理解是有缺陷的。 (儘管它也能很好地工作) – Aidan 2012-03-09 15:32:57
如果你這樣做會發生什麼:'Seq.map2 chooseBigger accumulator line |> Seq.toList |> seq'? – Daniel 2012-03-09 16:47:03