2

我正在编写一个 PHP 函数,该函数需要遍历一个指针数组,并为每个项目拉入该数据(无论是来自 MySQL 数据库还是平面文件)。有没有人有任何优化这个的想法,因为可能有成千上万的迭代?

我的第一个想法是拥有一个我处理的缓存数据的静态数组,任何修改只会更改该缓存数组,然后最后我可以将它刷新到磁盘。但是,在超过 1000 个项目的循环中,如果我只在数组中保留大约 30 个,这将毫无用处。每个项目都不是太大,但内存中的 1000 多个项目太多了,因此需要磁盘存储。

数据只是 gzip 压缩的序列化对象。目前我正在使用数据库来存储数据,但我想也许平面文件会更快(我不关心并发问题,我不需要解析它,只需解压缩和反序列化)。我已经有一个自定义迭代器,它将一次拉入 5 个项目(以减少数据库连接)并将它们存储在此缓存中。但同样,当我需要迭代数千个时使用 30 的缓存是相当没用的。

基本上我只需要一种方法来快速迭代这些项目。

4

4 回答 4

1

好吧,你还没有付出太多。你没有描述你的数据,你没有描述你的数据在做什么,或者你什么时候需要一个对象而不是另一个,以及这些对象是如何临时释放的,在什么情况下你需要它回来,以及.. .

所以任何人在这里说的任何话都将是在黑暗中的一个完整的镜头。

...因此,沿着这些思路,这是在黑暗中拍摄的。

如果您每次都只愿意在内存中保存 x 个项目,请为 x 个项目留出空间。然后,每次访问对象时,记下时间(这可能并不意味着时钟时间,而是可能意味着访问它们的顺序)。将每个项目保留在一个列表中(它可能不会在列表中实现,而是作为一个类似堆的结构),以便最近使用的项目更快地出现在列表中。当您需要将一个新项目放入内存时,您可以替换最长时间之前使用的项目,然后将该项目移到列表的前面。您可能需要保留项目的另一个索引,以便在需要时知道它们在列表中的确切位置。然后您要做的是查找项目所在的位置,根据需要链接其父指针和子指针,然后将其移动到列表的前面。

这称为LRU算法。这是虚拟内存的页面替换方案。它的作用是延迟你的瓶颈(磁盘 I/O),直到它可能无法避免。值得注意的是,该算法不能保证最佳替换,但它仍然表现得很好。

除此之外,我建议您在很大程度上并行化您的代码(如果可能的话),以便当一项需要撞击硬盘以加载或转储时,您可以让该处理器忙于实际工作。

< 编辑 > 根据您的评论,您正在研究神经网络。在您最初馈送数据的情况下(在校正阶段之前),或者当您积极使用它进行分类时,我不认为该算法是一个坏主意,除非没有可能的方法来适应内存中最常用的节点。

在校正阶段(也许是反向支持?),应该清楚你必须在内存中保留哪些节点......因为你已经访问过它们!

如果您的网络很大,那么您将无法摆脱没有磁盘 I/O 的情况。诀窍是找到一种方法来最小化它。</编辑>

于 2009-12-17T01:39:41.967 回答
0

显然,将它保存在内存中比其他任何方法都快。每个项目有多大?就算是每个1K,一万也只有10M。

于 2009-12-17T01:26:03.367 回答
0

获得所需数据后,您始终可以在循环中中断。这样它就不会继续循环。如果它是您存储的平面文件..您的服务器硬盘将遭受包含数千或数百万不同文件大小的文件。但是,如果您谈论的是存储在数据库中的整个实际文件。那么最好将它存储在一个文件夹中,然后将该文件的路径保存在数据库中。并尝试将提取的项目放入 XML 中。这样它更容易访问,它可以包含许多属性,用于提取项目的详细信息,例如(名称、上传日期等)。

于 2009-12-17T01:26:28.873 回答
0

您可以在第一次读取对象时使用 memcached 存储对象,然后在后续调用中使用缓存版本。Memcached 使用 RAM 来存储对象,所以只要你有足够的内存,你就会有很大的加速。memcached 有一个 php api

于 2009-12-17T01:43:00.650 回答