用C / C ++

时间:2015-08-17 10:03:44

标签: c++ c file-io

我有一个文件如下:

enter image description here

该文件由两部分组成:标题和数据。

数据部分被分成相同大小的页面。每个页面都包含特定指标的数据。可能需要多个页面(不需要连续)来保存单个度量的数据。每个页面都包含页眉和页面正文。页眉有一个名为“下一页”的字段,该字段是保存同一度量标准数据的下一页的索引。页面正文包含真实数据。所有页面都有相同的&固定大小(标头为20字节,主体为800字节(如果数据量小于800字节,则将填充0))。

标题部分由20,000个元素组成,每个元素具有关于特定度量的信息(点1 - >点20000)。元素具有称为“第一页”的字段,该字段实际上是包含度量标准数据的第一页的索引。

该文件最大可达10 GB。

要求:在最短时间内重新排序文件数据,即保存单个度量标准数据的页面必须是连续的,根据字母顺序从标准1到公制20000(标题部分必须相应更新)

明显的方法:对于每个指标,读取指标的所有数据(逐页),将数据写入新文件。但这需要很长时间,特别是在从文件中读取数据时。

有没有有效的方法?

3 个答案:

答案 0 :(得分:3)

一种可能的解决方案是从文件创建索引,其中包含您需要排序的页码和页面度量标准。将此索引创建为数组,以便第一个条目(索引0)对应于第一个页面,第二个条目(索引1)对应第二个页面等。

然后使用指定的指标对索引进行排序。

排序后,您最终得到一个包含新的第一个和第二个等条目的新数组,并且您按照排序索引的顺序读取输入文件写入输出文件。

答案 1 :(得分:2)

  

明显的方法:对于每个指标,读取指标的所有数据(逐页),将数据写入新文件。但这需要很长时间,特别是在从文件中读取数据时。

     

有没有有效的方法?

是。在获得可行的解决方案后,测量其效率,然后确定您希望优化的部分。优化的内容和方式在很大程度上取决于您在此获得的结果(您的瓶颈是什么)。

要考虑的一些通用事项:

  • 如果您有一组步骤读取单个指标的数据并将其移至输出,您应该能够并行化(有20组步骤而不是一组)。
  • 无论您运行代码的硬件是什么,10Gb文件都需要一些处理(令人信服的是,您可以在超级计算机上运行它,但我忽略了这种情况)。如果您/您的客户显示其进度/显示进度条,则您/您的客户可能会接受较慢的解决方案。
  • 不要使用字符串比较进行排序;

修改(发表评论)

考虑按如下方式执行阅读:

  • 为您要阅读的块创建块偏移列表

  • 创建固定大小的工作线程列表(例如,10名工作人员)

  • 每个空闲工作者将收到文件名和块偏移量,然后在文件上创建一个std :: ifstream实例,读取该块,并将其返回给接收对象(然后,请求另一个块号,如果有的话。)

  • 读取页面应传递给管理/存储页面的中央结构。

还要考虑分别管理块的内存(例如,当你知道要读取的块数时,抢占式地分配多个块的块)。

答案 2 :(得分:0)

我首先阅读标题部分,然后按字母顺序对指标进行排序。对于排序列表中的每个度量,我从输入文件中读取所有数据并写入输出文件。为了消除读取数据步骤中的瓶颈,我使用了内存映射。结果表明,使用内存映射时,与不使用内存映射时相比,5 GB输入文件的执行时间减少了5~6倍。这种方式暂时解决了我的问题。但是,我也会考虑@utnapistim的建议。