如何有效地索引文件?
How can I efficiently index a file?
我正在处理一个需要从一系列可能很大的文本文件 (~3+ GB) 中随机读取整行文本的应用程序。
线条的长度可以不同。
为了减少 GC
并创建不必要的字符串,我正在使用提供的解决方案: 来检测每个新行并将其一次性存储在地图中,从而生成索引lineNo => position
即:
// maps each line to it's corresponding fileStream.position in the file
List<int> _lineNumberToFileStreamPositionMapping = new List<int>();
- 浏览整个文件
- 当检测到
new line
增量时 lineCount
并将 fileStream.Position
添加到 _lineNumberToFileStreamPositionMapping
然后我们使用 API 类似于:
public void ReadLine(int lineNumber)
{
var getStreamPosition = _lineNumberToFileStreamPositionMapping[lineNumber];
//... set the stream position, read the byte array, convert to string etc.
}
该解决方案目前提供了良好的性能,但有两点我不喜欢:
- 因为我不知道文件中的总行数,所以我无法预分配一个
array
因此我必须使用一个 List<int>
,它可能会降低效率,将大小调整为原来的两倍我真的需要;
- 内存使用量,以约 1GB 的文本文件为例,其中包含约 500 万行文本,索引占用约 150MB,我真的很想尽可能减少它。
非常感谢任何想法。
使用List.Capacity手动增加容量,大概每1000行左右。
如果你想用性能换取内存,你可以这样做:不是存储每一行的位置,而是只存储每 100(或更多)行的位置。然后,当需要第 253 行时,转到第 200 行的位置并向前数 53 行。
我正在处理一个需要从一系列可能很大的文本文件 (~3+ GB) 中随机读取整行文本的应用程序。
线条的长度可以不同。
为了减少 GC
并创建不必要的字符串,我正在使用提供的解决方案:lineNo => position
即:
// maps each line to it's corresponding fileStream.position in the file
List<int> _lineNumberToFileStreamPositionMapping = new List<int>();
- 浏览整个文件
- 当检测到
new line
增量时lineCount
并将fileStream.Position
添加到_lineNumberToFileStreamPositionMapping
然后我们使用 API 类似于:
public void ReadLine(int lineNumber)
{
var getStreamPosition = _lineNumberToFileStreamPositionMapping[lineNumber];
//... set the stream position, read the byte array, convert to string etc.
}
该解决方案目前提供了良好的性能,但有两点我不喜欢:
- 因为我不知道文件中的总行数,所以我无法预分配一个
array
因此我必须使用一个List<int>
,它可能会降低效率,将大小调整为原来的两倍我真的需要; - 内存使用量,以约 1GB 的文本文件为例,其中包含约 500 万行文本,索引占用约 150MB,我真的很想尽可能减少它。
非常感谢任何想法。
使用List.Capacity手动增加容量,大概每1000行左右。
如果你想用性能换取内存,你可以这样做:不是存储每一行的位置,而是只存储每 100(或更多)行的位置。然后,当需要第 253 行时,转到第 200 行的位置并向前数 53 行。