二进制搜索 - 如何将文件中的+ 5M记录加载到Range <int> [] array?</int>中

时间:2013-03-07 16:15:09

标签: c# binary-search

这个问题是我之前关于二元搜索的问题(Fast, in-memory range lookup against +5M record table)的后续问题。

我有顺序文本文件,有超过5M条记录/行,格式如下。我需要将它加载到Range<int>[]数组中。如何及时做到这一点?

文件格式:

start int64,end int64,result int
start int64,end int64,result int
start int64,end int64,result int
start int64,end int64,result int
...

2 个答案:

答案 0 :(得分:0)

这是一个典型的(?)producer-consumer problem,可以使用多个线程来解决。在您的情况下,生产者正在从磁盘读取数据,而消费者正在解析这些行并填充数组。我可以看到两种不同的情况:

  • 生产者(消费者)比消费者快得多:在这种情况下你应该尝试使用更多的消费者线程;
  • 消费者(生产商)的速度快得多:除了影响您的硬件配置(例如购买更快的硬盘或使用RAID 0)之外,您不能做很多事情来加快速度。在这种情况下,我甚至不会使用多线程解决方案,因为它不值得增加复杂性。

This question可能会帮助您在C#中实现它。

答案 1 :(得分:0)

我会假设你有一个好的磁盘。扫描文件一次并计算条目数。如果你可以保证你的文件没有空白行,那么你可以只计算其中的换行符数 - 实际上并不解析每一行。

现在,您可以使用这么多条目分配一次数组。这避免了对阵列的过度重新分配:

var numEntries = File.ReadLines(filepath).Count();
var result = new Range<int>[numEntries];

现在再次读取文件并使用以下代码创建范围对象:

var i = 0;
foreach (var line in File.ReadLines(filepath))
{
   var parts = line.Split(',');
   result[i++] = new Range<int>(long.Parse(parts[0]), long.Parse(parts[1]), int.Parse(parts[2]);
}

return result;

根据需要加入一些错误处理。这段代码很容易理解。在目标环境中尝试一下。如果它太慢,那么你可以开始优化它。我不会过早地优化,因为这将导致更复杂的代码,可能不需要。