【问题标题】:Alternative for slow PHP SimpleXmlElement cast to string将慢速 PHP SimpleXmlElement 转换为字符串的替代方案
【发布时间】:2016-03-27 19:20:43
【问题描述】:

有谁知道将 SimpleXmlElement 转换为字符串的替代方法? 标准的字符串转换非常慢:

$myString = (string)$simpleXmlElement->someNode;

我需要知道哪个更快地查找具有特定文本值的元素:XPath 或遍历节点...所以我编写了一个简单的脚本来测量两种方式的 1000 次迭代的持续时间。

第一个结果是 XPath 慢得多,但后来我发现我忘记了节点遍历部分中的字符串转换。当我修复它时,节点行走要慢得多。 所以,只有 cast-to-string 翻转了整个结果。

请查看以下代码以了解当前的问题:

<pre>
<?php
//---------------------------------------------------------------------------
date_default_timezone_set('Europe/Amsterdam');
error_reporting(E_ALL);

//---------------------------------------------------------------------------
$data = <<<'EOD'
<?xml version="1.0" encoding="UTF-8" ?>
<root>
  <children>
    <child><test>ads</test></child>
    <child><test>sdf</test></child>
    <child><test>dfg</test></child>
    <child><test>fgh</test></child>
    <child><test>ghj</test></child>
    <child><test>hjk</test></child>
    <child><test>jkl</test></child>
    <child><test>ads</test></child>
    <child><test>sdf</test></child>
    <child><test>dfg</test></child>
    <child><test>fgh</test></child>
    <child><test>ghj</test></child>
    <child><test>hjk</test></child>
    <child><test>jkl</test></child>
    <child><test>123</test></child>
    <child><test>234</test></child>
    <child><test>345</test></child>
    <child><test>456</test></child>
    <child><test>567</test></child>
    <child><test>678</test></child>
    <child><test>789</test></child>
    <child><test>890</test></child>
    <child><test>90-</test></child>
    <child><test>0-=</test></child>
    <child><test>qwe</test></child>
  </children>
</root>
EOD;

$xml = new SimpleXMLElement($data);

$values = array('123', '234', '345', '456', '567', '678', '789', '890', '90-', '0-=', 'qwe');
$valCount = count($values);

$tries = 1000;

//---------------------------------------------------------------------------
echo("Running XPath...    ");
$startTime = microtime(true);
for ($idx=0; $idx<$tries; $idx++)
  $xml->xpath('/root/children/child[test="'.$values[($idx % $valCount)].'"]');
$duration = microtime(true) - $startTime;
echo("Finished in: $duration\r\n");

//---------------------------------------------------------------------------
echo("Running NodeWalk... ");
$startTime = microtime(true);
for ($idx=0; $idx<$tries; $idx++)
{
  $nodes = $xml->children->child;
  foreach ($nodes as $node)
    if ((string)$node->test == $values[($idx % $valCount)])
      break;
}
$duration = microtime(true) - $startTime;
echo("Finished in: $duration\r\n");

//---------------------------------------------------------------------------
?>
</pre>

换行时:

if ((string)$node->test == $values[($idx % $valCount)])

到:

if ($node->test == $values[($idx % $valCount)])

代码甚至可以查看更多节点,但速度仍然快很多。所以,在我看来,这里的字符串转换很慢。

有人有更快的字符串转换方法吗?

【问题讨论】:

  • 将节点转换为字符串需要遍历该节点下的整个子树。似乎很合乎逻辑,如果你想搜索树,你最好走一次,而不是两次——一次转换,一次搜索。
  • 看看3v4l.org/DY92Y。除非您使用 hhvm,否则差异似乎可以忽略不计。而且大多数时候 Nodewalk 似乎更快。
  • @Gordon 嗯,这很奇怪。这些数字和我的完全不同。也许那是因为我在本地使用 Windows。我会测试一下。

标签: php string performance casting simplexml


【解决方案1】:

令人惊讶的是,正如@Gordon 指出的那样,性能实际上并没有太大差异......在 Linux 上。

由于最初的测试只在 Windows 上进行,我在 Linux 上重新测试了它,你知道吗... XPath-way 和 node-walking-way 之间的区别已经消失了。

对我来说这就足够了,因为我实际上是为 Linux(产品平台)编写的。但是在为 Windows 构建时仍然需要注意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多