有没有办法保存对象的状态以便以后更快地重新加载?

时间:2009-08-15 15:22:26

标签: delphi performance

我正在处理的一段代码必须分析由另一个软件生成的外来文件格式 - 从游戏中“重放”更精确。在此重播中,玩家产生的每个动作都会以可变数量的参数保存 我的软件会对用户的操作进行分析,比如在整个游戏过程中每分钟生成一个动作图表等等......并且在内部提供详细信息,每个动作都用自己的方法转换为一个对象,但有几十个即使对于最简单的游戏,这种分析需要花费一些时间,而且我现在正在寻找一种方法来在重播已经被分析过一次时将其固定。

我有几个想法,但我不确定应该应用哪一个:
 1 - 某种序列化将动作的对象状态保存在磁盘上,以便可以直接从它重新加载对象?我不确定这会对性能产生重大影响,因为它仍然需要创建所有对象  2 - 手动创建每个对象类型的大型池,并在用户从重放移动到重放时重用它们,从而避免创建时间?

我不知道如何继续这里,所以如果您对如何快速设计这个有任何好主意,请随时分享。请注意,一旦分析,占用磁盘空间以保存重放状态不是问题,这些都是“高端”游戏玩家的计算机,因此只要加快进程,我就可以对消耗多少资源采取一些自由。 / p>

提前感谢您提供任何帮助

5 个答案:

答案 0 :(得分:8)

  • TComponent
  • 派生每个对象
  • 制作要保存的所有媒体资源已发布
  • 创建一个 root 组件作为其他人的所有者
  • 使用 TFileStream TMemoryStream 来存储和加载根

答案 1 :(得分:4)

你目前有

GameRecordOnDisk {contains many action defintions } 
                             ---> RepresentionOfActionsInMemory

您是否知道进行转型的时间在哪里?从磁盘读取?解析数据?创建对象?设置动作之间的联系(也许搜索事物列表?)。

我认为您需要获得一些性能工具并分析正在发生的事情。众所周知,性能调优不直观。你经常发现一条看似无害的代码行非常昂贵。

然后,您可能会被设计为设计更优化的磁盘表示,或使您的数据结构更高效或其他。但是如果没有事实,你就有可能小心地将一段代码的性能提高1000%,但却发现你只是删除了1%的总开销。

答案 2 :(得分:0)

Uwe Raabe表达的好主意。

作为另一种选择:

如果您知道事先创建的对象数量:在一个包中创建它们然后只需访问。

如果每次都是变量编号,但您知道它是10,000的订单,那么一次创建100个包中的对象。它会提高你的生产力但是仍然如此。我不认为创建对象是你的主要瓶颈。

答案 3 :(得分:0)

程序分析游戏文件后,将所有分析信息保存到文件中,名称与游戏文件相同,但后缀不同。

e.g。您在X40938.log中读取并输出X40938.ana(假设您需要ana作为后缀)。

然后每当有人使用您的程序分析游戏文件时,请检查相关的.ana文件。如果它存在,则加载(快速),否则分析游戏文件(慢)并保存.ana文件,以便下次快速。

如果程序可以更新游戏文件,那么您可以将游戏文件的时间戳(最后更改日期)与.ana文件的时间戳进行比较,以及游戏文件的时间戳是否晚于时间戳。 ana文件,然后你将不得不重新分析。

您担心的是再次创建对象会很慢。我对此表示怀疑。我确信这是对游戏数据的分析很慢。您应该发现加载预分析的数据要快得多。

答案 4 :(得分:0)

在MFC中有“序列化”的概念。

您可以使用任何语言进行操作。基本上你只是编写例程来遍历你的数据结构,当他们去的时候,他们会把二进制的基本数据写到你的文件中。

写出数组时,请确保在元素之前写入数组大小。

当基于指针编写结构时,首先写一个布尔值,告诉指针是否为空。

然后你写一个做同样事情的读者,除了它会读取数组的时候,它首先读取大小,分配数组并读取元素。在您读取指针的位置,首先读取布尔值。如果为0,则将指针设为null并跳过它。如果没有,请分配指针并继续读取其内容。

在MFC中,这两个函数实际上被编码为称为“Serialize”的常用例程。你在写作的时候基本上是在做深度优先的树步行,当你阅读的时候也是如此。

由于所有I / O都是二进制的,因此速度尽可能快。