Tôi đang xây dựng một trình phân tích cú pháp RSS bằng cách sử dụng lớp SimpleXML và tôi đã tự hỏi nếu sử dụng lớp DOMDocument sẽ cải thiện tốc độ của trình phân tích cú pháp. Tôi đang phân tích cú pháp một tài liệu rss có ít nhất 1000 dòng và tôi sử dụng gần như tất cả dữ liệu từ 1000 dòng đó. Tôi đang tìm phương pháp sẽ mất ít thời gian nhất để hoàn thành.SimpleXML vs DOMDocument performance
Trả lời
SimpleXML
và DOMDocument
đều sử dụng phân tích cú pháp tương tự (libxml2
), do đó phân tích khác biệt giữa chúng là không đáng kể.
này rất dễ dàng để xác minh:
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();
Trên máy tính của tôi, tôi có được về cơ bản không có sự khác biệt:
Time to complete 10000 reps:
time_load_dd: 17.725028991699
time_load_sxe: 17.416455984116
Vấn đề thực sự ở đây là những gì các thuật toán bạn đang sử dụng và những gì bạn đang làm với dữ liệu. 1000 dòng không phải là một tài liệu XML lớn. Sự chậm lại của bạn sẽ không được sử dụng bộ nhớ hoặc phân tích tốc độ nhưng trong logic ứng dụng của bạn.
Vâng, tôi đã gặp sự khác biệt hiệu suất HUGE giữa DomDocument
và SimpleXML
. Tôi có ~ 15 MB tệp XML lớn với khoảng 50 000 phần tử như thế này:
...
<ITEM>
<Product>some product code</Product>
<Param>123</Param>
<TextValue>few words</TextValue>
</ITEM>
...
Tôi chỉ cần "đọc" các giá trị đó và lưu chúng trong mảng PHP. Lúc đầu, tôi đã cố gắng 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
}
kịch bản đó đã chết sau 60 giây với thời gian thực hiện tối đa vượt quá lỗi. Chỉ có 15 000 mục 50k được phân tích cú pháp.
Vì vậy, tôi viết lại mã để SimpleXML
phiên bản:
$xml = new SimpleXMLElement($external_content);
foreach($xml->xpath('ITEM') as $item) {
$product_code = (string) $item->Product;
// ... some other operation
}
Sau 1 giây tất cả đã được thực hiện.
Tôi không biết các hàm đó được thực thi trong PHP như thế nào, nhưng trong ứng dụng của tôi (và với cấu trúc XML của tôi), thực sự, sự khác biệt hiệu suất thực sự lớn giữa DomDocument
và SimpleXML
.
Có một sự khác biệt lớn trong việc sử dụng xpath và chỉ nhận các phần tử theo thẻ của chúng. Đánh giá bằng cách các kịch bản đó hoạt động như thế nào, chức năng xpath thực sự không phục hồi tất cả các phần tử cùng một lúc, thay vào đó cung cấp cho bạn một đối tượng trình lặp - điều này sẽ nhẹ hơn và nhanh hơn đáng kể. Cũng giống như khi tải tệp - bạn có thể tải một tệp lớn cùng một lúc hoặc đọc từng dòng. Vì đọc từng dòng không yêu cầu tải mọi thứ vào bộ nhớ cùng một lúc, nó sẽ hoạt động tốt hơn. – SteveB
Nhận xét ở trên là chính xác, không phải về DomDocument vs SimpleXML, về cách bạn lặp lại. Thay đổi việc lặp trên DomDocument từ getElementsByTagName thành DOMXPath thay vào đó, làm cho nó nhanh như vậy. Các thử nghiệm của tôi trên một tài liệu ~ 120.000 yếu tố xác nhận điều này – BobbyTables
Tôi cũng muốn thêm rằng không chỉ * phân tích cú pháp * là giống nhau, nhưng các tác vụ phổ biến nhất chỉ cung cấp về cùng một hiệu suất. Nếu ứng dụng của bạn chậm với một ứng dụng, nó sẽ chậm với ứng dụng kia. –
Cảm ơn đó là một cuộc biểu tình rất tốt. Tôi chỉ còn một câu hỏi nữa. Điều gì xảy ra nếu tôi chỉ muốn nhận giá trị của một thẻ từ nguồn cấp dữ liệu. Cái nào sẽ nhanh hơn hoặc là thời gian khác biệt không đáng kể như trên? Cảm ơn! – mhlas7
Bạn cần cụ thể hơn về những gì bạn đang đánh giá. (Đối với một, DOM/SXE không có "thẻ"!) Có nhiều cách để lấy một phần tử - bằng cách duyệt qua hoặc bởi XPath, và với XPath có nhiều XPath tương đương sẽ thực hiện khác nhau. Tại sao bạn không chuẩn? Quan trọng hơn, thậm chí bạn có * gặp phải * cần tối ưu hóa không? Nhiều khả năng bạn không cần lo lắng về tốc độ và tối ưu hóa vi mô sớm. –