我有一个文件如下:
该文件由两部分组成:标题和数据。
数据部分被分成相同大小的页面。每个页面都包含特定指标的数据。可能需要多个页面(不需要连续)来保存单个度量的数据。每个页面都包含页眉和页面正文。页眉有一个名为“下一页”的字段,该字段是保存同一度量标准数据的下一页的索引。页面正文包含真实数据。所有页面都有相同的&固定大小(标头为20字节,主体为800字节(如果数据量小于800字节,则将填充0))。
标题部分由20,000个元素组成,每个元素具有关于特定度量的信息(点1 - >点20000)。元素具有称为“第一页”的字段,该字段实际上是包含度量标准数据的第一页的索引。
该文件最大可达10 GB。
要求:在最短时间内重新排序文件数据,即保存单个度量标准数据的页面必须是连续的,根据字母顺序从标准1到公制20000(标题部分必须相应更新)
明显的方法:对于每个指标,读取指标的所有数据(逐页),将数据写入新文件。但这需要很长时间,特别是在从文件中读取数据时。
有没有有效的方法?
答案 0 :(得分:3)
一种可能的解决方案是从文件创建索引,其中包含您需要排序的页码和页面度量标准。将此索引创建为数组,以便第一个条目(索引0
)对应于第一个页面,第二个条目(索引1
)对应第二个页面等。
然后使用指定的指标对索引进行排序。
排序后,您最终得到一个包含新的第一个和第二个等条目的新数组,并且您按照排序索引的顺序读取输入文件写入输出文件。
答案 1 :(得分:2)
明显的方法:对于每个指标,读取指标的所有数据(逐页),将数据写入新文件。但这需要很长时间,特别是在从文件中读取数据时。
有没有有效的方法?
是。在获得可行的解决方案后,测量其效率,然后确定您希望优化的部分。优化的内容和方式在很大程度上取决于您在此获得的结果(您的瓶颈是什么)。
要考虑的一些通用事项:
修改(发表评论)
考虑按如下方式执行阅读:
为您要阅读的块创建块偏移列表
创建固定大小的工作线程列表(例如,10名工作人员)
每个空闲工作者将收到文件名和块偏移量,然后在文件上创建一个std :: ifstream实例,读取该块,并将其返回给接收对象(然后,请求另一个块号,如果有的话。)
读取页面应传递给管理/存储页面的中央结构。
还要考虑分别管理块的内存(例如,当你知道要读取的块数时,抢占式地分配多个块的块)。
答案 2 :(得分:0)
我首先阅读标题部分,然后按字母顺序对指标进行排序。对于排序列表中的每个度量,我从输入文件中读取所有数据并写入输出文件。为了消除读取数据步骤中的瓶颈,我使用了内存映射。结果表明,使用内存映射时,与不使用内存映射时相比,5 GB输入文件的执行时间减少了5~6倍。这种方式暂时解决了我的问题。但是,我也会考虑@utnapistim的建议。