优化读/写海量数据(C+;+;) 我希望优化C++软件模拟应用的读写数据。被称为“映射”的数据基本上由整数、双精度、浮点和单个枚举组成。大多数地图数据的大小是固定的,但其中一小部分可能会有所不同 (从几KB到几KB)大小。几个这样的映射(通常为数百万)在应用程序开始时计算一次,然后存储在单个二进制文件中,以便在每个模拟时间步进行解析

优化读/写海量数据(C+;+;) 我希望优化C++软件模拟应用的读写数据。被称为“映射”的数据基本上由整数、双精度、浮点和单个枚举组成。大多数地图数据的大小是固定的,但其中一小部分可能会有所不同 (从几KB到几KB)大小。几个这样的映射(通常为数百万)在应用程序开始时计算一次,然后存储在单个二进制文件中,以便在每个模拟时间步进行解析,c++,optimization,C++,Optimization,由于有几百万个映射,这个二进制文件的解析速度非常慢,其中fseek和fread是主要的瓶颈。我正在寻找另一种方法来做同样的事情 任何指针?使用内存映射文件() 既然您没有提到您正在运行此操作系统的操作系统,那么您是否查看了文件的内存映射,然后使用标准内存例程在运行过程中“遍历”文件 这样,您就不用使用fseek/fread,而是使用指针算法。将一个文件从源文件复制到目标文件。这可以提高性能 您可以研究的其他事情是,将文件拆分为较小的文件,并使用与时间单位相对应的哈希值关闭然后打开下一个文件以继续

由于有几百万个映射,这个二进制文件的解析速度非常慢,其中fseek和fread是主要的瓶颈。我正在寻找另一种方法来做同样的事情


任何指针?

使用内存映射文件()

既然您没有提到您正在运行此操作系统的操作系统,那么您是否查看了文件的内存映射,然后使用标准内存例程在运行过程中“遍历”文件

这样,您就不用使用fseek/fread,而是使用指针算法。将一个文件从源文件复制到目标文件。这可以提高性能


您可以研究的其他事情是,将文件拆分为较小的文件,并使用与时间单位相对应的哈希值关闭然后打开下一个文件以继续模拟,这样可以处理主机操作系统可以更积极地缓存的较小文件

将计算出的数据存储在关系数据库中。

在这种情况下可能与此无关,但我通过写入压缩数据(zlib)和动态解压缩,在一个文件读写量大的应用程序中成功地提高了性能,读写时间的减少与CPU负载的增加是一个胜利

或者,如果您的问题是内存中无法容纳大量数据,并且希望将磁盘用作缓存,则可以查看memcached,它提供了一个可扩展的分布式内存缓存。

“数百万”地图听起来不像很多数据。 是什么阻止您将所有数据保留在内存中


另一个选择是使用一些适合您需要的标准文件格式,例如,(使用SQL存储/检索数据)或一些特定的格式,或者使用诸如.< /p> 之类的定义您自己的格式。您可以考虑使用内存映射文件。例如,请参阅,因为它们提供了方便的实现

您也可以考虑使用它提供针对大型基于文件的数据集的类似STL的功能。 还有一个问题——如果您希望像迭代器一样访问您的数据,请查看


如果您不想玩这些花哨的把戏,可以提供额外的二进制文件,其中包含具有结构的文件的索引(包含结构起始偏移量的偏移量)。这将提供间接的随机访问。

此想法的有效性取决于您的访问模式,但如果您不在每个周期查看可变大小的数据,则可以通过重新排列文件结构来加快访问速度:
而不是像这样编写结构的直接转储:

struct { 
  int x;
  enum t;
  int sz
  char variable_data[sz];
};
您可以先编写所有固定大小的部件,然后再存储可变部分:

struct {
  int x;
  enum t;
  int sz;
  long offset_to_variable_data;
};
现在,当您在每个周期解析文件时,您可以一次线性读取N条记录。只有在需要获取可变大小的数据时,才需要处理fseek。您甚至可以考虑将该变量部分保存在一个单独的文件中,这样您也只能通过该文件向前读取。

如果按照其他人的建议使用内存映射文件,此策略甚至可以提高性能。

框架喜欢并提供对内存映射文件的平台独立访问。这将大大加快解析速度