如何提高PHP的XML加载速度?

4

我要放弃潜伏状态,终于提出一个问题...

我需要知道如何提高从XML文件获取数据的PHP脚本的性能。

一些背景:

  • 我已经确定瓶颈在CPU方面,但希望在承受处理器成本之前优化脚本的性能。具体来说,脚本中最消耗CPU的部分是XML加载。

  • 我使用XML存储对象数据的原因是数据需要通过浏览器Flash界面访问,并且我们希望在该领域提供快速的用户访问。然而,该项目仍处于早期阶段,如果最佳做法是完全放弃XML,那么这也是一个好答案。

  • 大量数据: 目前大约绘制了大约100k个对象,尽管通常是小型的,但必须全部包含在脚本中,并可能有一些罕见的例外情况。数据集将随时间增长。

  • 频繁运行: 理想情况下,我们每小时运行大约50k次脚本; 实际上,我们会安排每小时运行约1k次脚本。这与数据大小相结合,使性能优化变得非常重要。

  • 已经采取了优化措施,对相同的数据进行多次运行,而不是为每次运行加载数据,但仍然需要太长时间。运行通常应使用用户所做的修改后的“新鲜”数据。

3个回答

3

仅作澄清:您正在加载的数据是否来自XML文件以在其当前状态下进行处理,并且是否在发送到Flash应用程序之前进行了修改?

看起来最好使用数据库存储数据并根据需要推出XML,而不是首先读取XML;如果生成XML文件变慢,可以将文件缓存为它们生成的内容,以避免重复生成相同的文件。


这就是我要建议的。+1 - ceejayoz
是的,如果你可以访问到它,那么将100k个对象存储在嵌入式数据库或专用数据库中会更好;然后你可以仅生成客户端需要的XML位。 - Mercer Traieste
澄清一下:Flash界面和运行是完全独立的,除了运行会修改一些最终可显示的数据。但是,无论用户是否查询对象,运行都是独立的。 来自XML的数据处于其当前状态;当发送到Flash时,它不会被修改。然而,用户可以通过界面对加载的文件进行更改。问题是,除了更快的用户访问速度外,使用数据库是否加快了运行速度?我们目前更关心这个。 - Polymeron
在实际运行中,似乎可以通过使用数据库来提高性能;与每次解析XML相比,加载数据的开销将显着减少。至少这将降低每次运行的成本。 - Mathew Hall

1
如果XML比较静态,您可以将其缓存为PHP数组,类似于以下内容:
<xml><foo>bar</foo></xml>

被缓存到文件中

<?php return array('foo' => 'bar');

将XML数组化后,PHP应该会更快地进行包含。


这是一个好的答案,但我们已经同时执行了几次;预计 XML 不会保持静态状态超过几秒钟,但我们允许少量更改在几次运行中滑过几分钟。之后,我们必须接收所有更改,这意味着需要重新创建数组。仍然非常 CPU 密集。 - Polymeron

0

每小时约1千次,每小时3600秒,超过3次/秒(更不用说每小时5万次)...

有很多问题。其中一些是:

  • 您的php脚本是否需要在每个单独运行中读取/处理数据源的所有记录?如果不是,它需要什么样的子集(~大小、标准等)
  • 同样的问题适用于Flash应用程序+谁发送数据?PHP脚本?“直接”请求完整的静态xml文件?
  • 对数据源执行了哪些操作?
  • 您是否需要某种并发机制?
  • ...

而且,仅因为您想向Flash客户端提供xml数据,并不意味着您必须将xml数据存储在服务器上。例如,如果客户端只需要可用记录的一个小子集,那么不将数据存储为xml,而是使用更适合速度和“可搜索性”的东西,然后根据客户端请求的数据以及数据如何/多少更改,在现场创建子集的xml输出可能会更快,也许还可以辅助一些缓存。

编辑:假设您真的非常需要整个数据集并且需要连续模拟。那么,您可能希望考虑一种持续的流程,将完整的“世界模型”保存在内存中,并在每次运行(世界时钟周期)时对该模型进行操作。这样,至少您不必在每个周期加载数据。但是,这样的进程通常不是用php编写的。

澄清一下,运行应该在后台工作,处理最终将显示给用户的数据。
  • 我们需要每个对象的所有数据来运行。
  • 当用户查看接口时,接口调用特定的 XML 文件以了解要显示什么。
  • 不需要并发机制-我认为这方面没问题。
对于用户来说,可搜索性非常好,但对于后台运行来说,使用数据库是否更高效?这是当前的问题。
- Polymeron
如果这是一个后台进程,为什么需要反复读取/加载整个数据集?如果你说必须这样做,我们可能会相信你;-) 但很多时候在 php 论坛上问这样的问题,归根结底就是"不,你不需要(几乎-)连续的模拟来完成这个任务"。你能更具体地说明数据集和每次运行想要执行的操作吗? - VolkerK
然后尝试摆脱文件或至少重复的加载操作。即一个连续运行的进程,a) 进行模拟计算,b) 接受和服务于对数据子集的请求,c) 处理修改数据的请求。因此,这个过程将把新数据集成到其世界模型中(并可能将其作为备份存储在数据库中),而不是上传一个存储在服务器上的文件。 - VolkerK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接