【发布时间】: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