【发布时间】:2016-11-17 18:00:46
【问题描述】:
我在这里遇到了一个棘手的情况。在通过 HDFDotNet API 将大型 CSV 数据集写入 H5 文件时,我试图避免出现内存不足的异常。但是,当尝试对与第一次迭代大小相同的文件数据进行第二次循环时,我得到了内存不足异常,即使第一个有效而第二个无效,并且使用的内存量应该是远低于~1.2GB 的上限。由于 API 的限制,我已经确定了一次要读取的块的大小以及一次需要写入的块的大小。 CSV 文件长约 105k 行,宽约 500 列。
private void WriteDataToH5(H5Writer h5WriterUtil)
{
int startRow = 0;
int skipHeaders = csv.HasColumnHeaders ? 1 : 0;
int readIntervals = (-8 * csv.NumColumns) + 55000;
int numTaken = readIntervals;
while (numTaken == readIntervals)
{
int timeStampCol = HasTimestamps ? 1 : 0;
var readLines = File.ReadLines(this.Filepath)
.Skip(startRow + skipHeaders).Take(readIntervals)
.Select(s => s.Split(new char[] { ',').Skip(timeStampCol)
.Select(x => Convert.ToSingle(x)).ToList()).ToList();
//175k is max number of cells that can be written at one time
//(unconfirmed via API, tested and seems to be definitely less than 200k and 175k works)
int writeIntervals = Convert.ToInt32(175000/csv.NumColumns);
for (int i = 0; i < readIntervals; i += writeIntervals)
{
long[] startAt = new long[] { startRow, 0 };
h5WriterUtil.WriteTwoDSingleChunk(readLines.Skip(i).Take(writeIntervals).ToList()
, DatasetsByNamePair[Tuple.Create(groupName, dataset)], startAt);
startRow += writeIntervals;
}
numTaken = readLines.Count;
GC.Collect();
}
}
我最终在第二次通过 readlines 部分时遇到内存不足异常
var readLines = File.ReadLines(this.Filepath)
.Skip(rowStartAt).Take(numToTake)
.Select(s => s.Split(new char[] { ',' }).Skip(timeStampCol)
.Select(x => Convert.ToSingle(x)).ToList()).ToList();
在这种情况下,我的读取间隔 var 会达到 50992,而 writeIntervals 会达到大约 350。谢谢!
【问题讨论】:
-
尽可能避免解析任务。见stackoverflow.com/questions/9642055/…你会遇到转义数据、多行数据等问题。使用别人的工作
-
我最终找出了问题所在,这与我通过 API 写入 H5 文件的方式有关。我之前已将其上的块大小设置为 {1,1} 默认值,并且尝试写入更大的块会导致它崩溃。此外,将压缩级别设置为 6-8 也有很大帮助。