2012-02-20 125 views
7

我使用SimpleXML Class构建RSS解析器,我在想如果使用DOMDocument类会提高解析器的速度。我正在解析一个至少有1000行的rss文档,并且使用了几乎所有1000行数据。我正在寻找将花费最少时间完成的方法。SimpleXML vs DOMDocument性能

回答

19

SimpleXMLDOMDocument都使用相同的解析器(libxml2),所以它们之间的解析差是可忽略的。

这是很容易验证:

function time_load_dd($xml, $reps) { 
    // discard first run to prime caches 
    for ($i=0; $i < 5; ++$i) { 
     $dom = new DOMDocument(); 
     $dom->loadXML($xml); 
    } 
    $start = microtime(true); 
    for ($i=0; $i < $reps; ++$i) { 
     $dom = new DOMDocument(); 
     $dom->loadXML($xml); 
    } 
    $stop = microtime(true) - $start; 
    return $stop; 
} 
function time_load_sxe($xml, $reps) { 
    for ($i=0; $i < 5; ++$i) { 
     $sxe = simplexml_load_string($xml); 
    } 
    $start = microtime(true); 
    for ($i=0; $i < $reps; ++$i) { 
     $sxe = simplexml_load_string($xml); 
    } 
    $stop = microtime(true) - $start; 
    return $stop; 
} 


function main() { 
    // This is a 1800-line atom feed of some complexity. 
    $url = 'http://feeds.feedburner.com/reason/AllArticles'; 
    $xml = file_get_contents($url); 
    $reps = 10000; 
    $methods = array('time_load_dd','time_load_sxe'); 
    echo "Time to complete $reps reps:\n"; 
    foreach ($methods as $method) { 
     echo $method,": ",$method($xml,$reps), "\n"; 
    } 
} 
main(); 

在我的机器,我得到基本没有区别:

Time to complete 10000 reps: 
time_load_dd: 17.725028991699 
time_load_sxe: 17.416455984116 

这里真正的问题是你使用,你是用做的哪些算法数据。 1000行不是一个大的XML文档。你的减速将不会在内存使用或分析速度上,而是在你的应用程序逻辑中。

+0

我还补充说,不仅*解析*是相同的,但最常见的任务也提供几乎相同的性能。如果你的应用程序运行缓慢,那么其他应用程序将会很慢。 – 2012-02-20 23:48:17

+0

谢谢,这是一个非常好的示范。我还有一个问题。如果我只想从Feed中获取一个标签的值,该怎么办?哪一个会更快,或者与上面的时间差别微不足道?谢谢! – mhlas7 2012-02-21 03:44:16

+2

您需要更具体地了解您正在进行基准测试。 (例如,DOM/SXE没有“标签”!)有多种获取元素的方法 - 通过遍历或XPath,而XPath有多个等效的XPath,它们的表现会有所不同。你为什么不进行基准测试?更重要的是,你是否曾经遇到*需要优化?很可能你根本不需要担心速度,并且过早地进行微观优化。 – 2012-02-21 15:35:05

-1

那么,我遇到了DomDocumentSimpleXML之间巨大的性能差异。我有〜15 MB,像这样大约50 000元大XML文件:

... 
<ITEM> 
    <Product>some product code</Product> 
    <Param>123</Param> 
    <TextValue>few words</TextValue> 
</ITEM> 
... 

我只需要“读”这些值,并将其保存在PHP数组。起初,我试图DomDocument ......

$dom = new DOMDocument(); 
$dom->loadXML($external_content); 
$root = $dom->documentElement; 

$xml_param_values = $root->getElementsByTagName('ITEM'); 
foreach ($xml_param_values as $item) { 
    $product_code = $item->getElementsByTagName('Product')->item(0)->textContent; 
    // ... some other operation 
} 

该脚本去世后,60秒内最大的执行时间超过错误。只有15000个50k的项目被解析。

所以我重写了代码SimpleXML版本:

$xml = new SimpleXMLElement($external_content); 
foreach($xml->xpath('ITEM') as $item) { 
    $product_code = (string) $item->Product; 
    // ... some other operation 
} 

1秒一切都完成后。

我不知道这些函数是如何在PHP中内部实现的,但在我的应用程序(以及我的XML结构)中,DomDocumentSimpleXML之间确实存在巨大的性能差异。

+5

使用xpath和通过标签获取元素存在巨大差异。根据这些脚本的行为来判断,xpath函数实际上不会一次恢复所有元素,而是为您提供一个迭代器对象 - 这将显着更轻且更快。 与加载文件相同 - 您可以一次加载大文件或每行读取一行。由于读取每一行不需要将所有内容一次加载到内存中,它的性能会更好。 – SteveB 2015-06-25 08:36:34

+3

上面的评论是正确的,它不是关于DomDocument与SimpleXML,它关于你如何迭代。相反,将DomDocument上的迭代从getElementsByTagName更改为DOMXPath,可以使其一样快速。我对大约120.000个元素文件的测试证实了这一点 – BobbyTables 2015-10-28 11:53:17