【问题标题】:C++: Is it more efficient to store data or continually read itC++:存储数据还是持续读取数据效率更高
【发布时间】:2018-08-09 22:51:37
【问题描述】:

好的,我正在开发一个游戏项目。刚刚完成重建我前段时间设计的游戏引擎。我正在考虑制作一种专有文件类型来存储数据,而不是使用像 sqlite 这样的数据库。

着眼于在不深入研究的情况下,尽可能高效、快速地在游戏中进行这项工作。然后随着时间的推移不断改进。

我的问题是:从文件中加载数据并将其存储在数据管理器类中以供重用是否更有效?还是从文件中不断拉取整体效率更高?

假设文件的数据遵循某种形式的一致结构。我们正在查看最大的“表格”,大约有 30 列,大约有 1000 行数据。

【问题讨论】:

  • 视情况而定,如果您可以将其全部保存在 RAM 中并有效地搜索,最好加载一次并保留在那里。如果太多,你应该使用磁盘。丢弃一段时间未使用的数据的混合解决方案可能是保留一些内存的最佳方式。
  • 内存中的缓存总是会更快,但是...您有可用的内存来保存它吗?是否需要缓存和持有?如果您很少访问并且有足够的其他东西在快速或缓慢地进行数据管理器可能完全无关紧要。从最容易写的开始,看看有没有影响。
  • 30 列 x 1000 行很小。
  • 你可以让操作系统内存管理器使用内存映射文件来处理这个问题。
  • 这里没有足够的信息可以为您提供任何类型的明确答案。对您的代码进行基准测试,并根据您的具体情况找出答案。

标签: c++ performance storage


【解决方案1】:

这是一个“每个计算机程序员都应该知道的延迟数字”的方便图表

图表的最右侧(红色)表示从磁盘读取 1 MB 所需的时间。绿色列与从 RAM 中读取的值相同。

这向我们表明,您应该几乎做任何事情,以避免直接与磁盘交互。将数据保存在 RAM 中是件好事。将数据保存在磁盘上是不好的。 (内存映射文件可能会提供一种处理方式。)

除此之外,重新发明轮子几乎总是错误的解决方案。 Sqlite 工作得很好。如果它不适合您的需求,还有其他文件类型。

如果您“希望在不深入研究的情况下尽快高效、快速地在游戏中进行这项工作。然后随着时间的推移不断改进”,您将如果您重用针对常见问题的现有解决方案,您会发现这是最容易做到的。

【讨论】:

  • 正如我在回答中所说,如果您继续读取相同的数据,将 RAM 访问时间与磁盘访问时间进行比较是不公平的,因为在访问磁盘之前,您将遇到 C 运行时缓存、操作系统磁盘缓存和磁盘控制器缓存本身,因此您可能只会支付延迟损失(由于上下文切换),而不是真正的磁盘读取时间损失。
  • @MatteoItalia:承认,尽管当您可以设计避免该问题的解决方案时,依靠一系列不透明的缓存来避免巨大的延迟命中似乎是一个糟糕的选择。
【解决方案2】:

继续读取文件通常不是一个好主意;现代操作系统确实保留了大型 IO 缓存(因此,如果您继续读取相同的内容,它不会真正访问磁盘),但系统调用当然比直接访问内存更繁重——尽管,无论是对于您的具体情况,这实际上将是一个性能问题,无法根据您提供的信息来判断。另一方面,如果您有大量数据要访问,则将其全部保存在内存中可能会造成浪费、加载​​缓慢,并且在内存压力下会导致分页。

解决这个难题的简单方法是将文件映射到内存中;数据会在需要时自动从磁盘中提取,除非系统处于内存压力之下,否则经常访问的页面仍会缓存在 RAM 中,从而保证您快速访问。

当然,这只有在您需要映射的数据小于地址空间时才可行,但鉴于您提供的示例(30 列/1000 行,这真的很小),这根本不应该是一个问题.

【讨论】:

    【解决方案3】:

    如果您可以将数据保存在 RAM 中,那么它的效率会更高。这是因为您的计算机访问 RAM、缓存或 CPU 寄存器中的值比从硬盘驱动器中获取值更快。从硬盘驱动器读取需要从操作系统驱动程序中获取大量时间;因此保存数据效率更高

    【讨论】:

    • 可能比您在此处解决的复杂性要复杂得多。问题本身不够详细,无法提供任何具体的答案。
    猜你喜欢
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多