国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++ Xml解析的效率比較(Qt/TinyXml2/RapidXml)

2019-11-08 01:53:23
字體:
來源:轉載
供稿:網友

C++ xml解析的效率比較(Qt/TinyXml2/RapidXml)


C Xml解析的效率比較QtTinyXml2RapidXml問題背景測試環境Qt - QDomDocumentTinyXml-2RapidXml總結


通常我們在一些軟件的初始化或者保存配置時都會遇到對XML文件的操作,包括讀寫xml文件,解析內容等等。在我的工作中就遇到了這么一個問題,就是在ARM平臺下Qt解析xml文件非常的慢,最初懷疑是我的操作有問題或者是ARM平臺下的文件操作本身就很慢,于是就開始調查到底是哪里的效率問題,下面是一些測試分享給大家。

問題背景

下面一段代碼是前面提到的運行效率低的一段代碼:

QString filename = "...";QFile file( filename );//< step1 open fileif( !file.open(QIODevice::ReadOnly) ){ qDebug() << "failed in opening file!"; return false;}//< step2 read file contentQDomDocument doc; //< #include <qdom.h>if( !doc.setContent( &file ) ){ qDebug() << "failed in setting content!"; file.close(); return false;}file.close();... //< Operations on the content of file!

起初以為是文件打開和關閉耗時太多,所以在文件open和close函數前后都獲取了系統時間來測試了函數消耗時間,結果是耗時很短,反而是 doc.setContent 耗費了非常長的時間,這才發現原來是Qt獲取XML文件內容且Dom模型結構花費了太多時間,所以我們開始尋求效率更高的解決方案。

測試環境

Windows: system:windows 10 cpu: intel core-i5-5200u @2.2GHz IDE: visual studio 2010 compiler: VC10

linux: system: Debian 4.4.5-8 cpu: intel core-i5-3450 @3.3GHz IDE: VIM compiler: gcc version 4.4.5

Qt版本: 4.8.4 用來測試的文件名為 DriverConfig.xml,大小為245Kb,共1561行,大部分內容為中文 比較項有 TinyXml2, QDomDocument,因為從接口來看這兩者的操作方式很類似,后面我會加入其它的xml解析庫的比較,如 xmlbooster 等。

Qt - QDomDocument

下面是利用Qt中的xml支持來讀取文件內容的源代碼:

#include <QtCore/QCoreapplication>#include <qdom.h>#include <QFile>#include <QIODevice>#include <iostream>#ifdef Q_OS_WIN# include <Windows.h>#else# include <sys/time.h>#endifusing std::cout;using std::endl;#define TEST_TIMES 10int main(int argc, char *argv[]){ QCoreApplication a(argc, argv);#ifdef Q_OS_WIN //< windows long tStart = 0; long tEnd = 0; LARGE_INTEGER nFreq; LARGE_INTEGER nStartTime; LARGE_INTEGER nEndTime; double time = 0.; QueryPerformanceFrequency(&nFreq); QFile file( "D:/DriverConfig.xml" ); QDomDocument doc; for( int i = 0; i < TEST_TIMES; ++i ) { doc.clear(); //< step1 open file if( !file.open(QIODevice::ReadOnly) ) { cout << "failed to open file!" << endl; continue; } Sleep( 100 ); QueryPerformanceCounter(&nStartTime); //< step2 set content if( !doc.setContent(&file) ) { cout << "Failed to read xml file!" << endl; } QueryPerformanceCounter(&nEndTime); time = (double)(nEndTime.QuadPart-nStartTime.QuadPart) / (double)nFreq.QuadPart * 1000.; //< ms cout << " seting content costs " << time << "ms" << endl; file.close(); Sleep( 100 ); }#else //< LINUX timeval starttime, endtime; QFile file( "/home/liuyc/DriverConfig.xml" ); QDomDocument doc; double timeuse = 0.; double timeAverage = 0.; for( int i = 0; i < TEST_TIMES; ++i ) { doc.clear(); //< step1 open file if( !file.open(QIODevice::ReadOnly) ) { cout << "failed to open file!" << endl; continue; } sleep( 1 ); //< delay for 1s gettimeofday( &starttime, 0 ); //< step2 set content if( !doc.setContent(&file) ) { cout << "Failed to read xml file!" << endl; continue; } gettimeofday( &endtime, 0 ); timeuse = 1000000. * (endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - starttime.tv_usec; timeuse *= 0.001 ; timeAverage += timeuse; cout << " reading files costs : " << timeuse << "ms" << endl; file.close(); sleep( 1 ); //< delay for 1s } timeAverage /= TEST_TIMES; cout << " The End *****************/n average costs = " << timeAverage << "ms" << endl; #endif return a.exec();}

下面來看看windows下的運行結果: 這里寫圖片描述 當時我的反應是 WTF?? 為什么同一個函數讀同一個文件十次會有這么大的差異所以我才會在文件打開和關閉時分別都加了延時,希望避免文件開關的過程對這個函數產生的影響,結果依然沒有解決這個問題,這個問題希望有大神幫我解答一下!

那下面我們來看linux下的運行結果: 這里寫圖片描述 顯然,linux下這個時間相對的穩定可信,所以我們后面的測試也只要以linux下的時間作為參考。

TinyXml-2

下面我們來看利用tinyxml2實現讀取的源代碼:

#include <iostream>#include "tinyxml2.h"#ifdef _WIN32#include <Windows.h>#else#include <sys/time.h>#endifusing namespace tinyxml2;using std::cout;using std::endl;#define TEST_TIMES 10int main(){#ifndef _WIN32 //< linux ------------------------------------------------ tinyxml2::XMLDocument doc; timeval starttime, endtime; double timeuse = 0.; double timeAverage = 0.; for( int i = 0; i < TEST_TIMES; ++i ) { gettimeofday( &starttime, 0 ); if( XML_SUCCESS != doc.LoadFile( "/home/liuyc/DriverConfig.xml" ) ) { cout << "failed in load xml file! _ " << i << endl; continue; } gettimeofday( &endtime, 0 ); timeuse = 1000000. * (endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - starttime.tv_usec; timeuse *= 0.001 ; cout << " reading files costs : " << timeuse << "ms" << endl; timeAverage += timeuse; } timeAverage /= TEST_TIMES; cout << " /n** The end *******************/n the average costs = " << timeAverage << "ms" << endl;#else //< windows --------------------------------------------------- LARGE_INTEGER nFreq; LARGE_INTEGER nStartTime; LARGE_INTEGER nEndTime; double time = 0.; QueryPerformanceFrequency(&nFreq); tinyxml2::XMLDocument doc; for( int i = 0; i < TEST_TIMES; ++i ) { QueryPerformanceCounter(&nStartTime); if( XML_SUCCESS != doc.LoadFile( "D:/DriverConfig.xml" ) ) { cout << "failed in load xml file! _ " << i << endl; continue; } QueryPerformanceCounter(&nEndTime); time = (double)(nEndTime.QuadPart-nStartTime.QuadPart) / (double)nFreq.QuadPart * 1000.; //< ms cout << " reading files costs : " << time << "ms" << endl; } cout << endl; system("pause");#endif //< end of windows --------------------------------------------------- return 0;}

接下來先看linux下的運行結果(windows下的運行結果已經沒有太多參考價值了): linux_tinyxml_result linux下的表現依然很穩定,這里我們可以得出一個很明顯的結論,tinyxml的處理效率要比QDomDocument的處理效率高很多(這里的數據大致是4倍,但不包括對于xml文件內部信息的處理的其他函數接口的調用)。

雖然沒什么參考價值,但還是看一下windows下的測試結果: windows_tiny_result 這里效率也明顯的比Windows Qt提升很多,而且執行時間也相對穩定了一,所以前一個測試中運行時間十分不穩定的情況暫定為Qt本身實現的問題,具體是什么問題或者在高版本的Qt里面是否已解決尚無答案。

RapidXml

注:RapidXml版本: 1.13 在RapidXml Manual的介紹中可以看到它和TinyXml以及其他的一些xml解析庫做了對比(這里面tinyXml是最慢的),原文中介紹這是目前Xml解析最快的

As a rule of thumb, parsing speed is about 50-100x faster than Xerces DOM, 30-60x faster than TinyXml, 3-12x faster than pugxml, and about 5% - 30% faster than pugixml, the fastest XML parser I know of.

所以這里我也想要試試看RapidXml在內容解析時的效率表現,下面是源代碼:

#include <iostream>#include "rapidxml.hpp"#include "rapidxml_同樣,先看linux下運行的結果: linux_rapidxml_result 效率確實為 TinyXml2 的2.x倍,但是并沒有像 rapidXml 的說明手冊里說的有30~60倍的效率差異(手冊中是和TinyXml比較的,而不是TinyXml2),這里我不清楚到底是TinyXml2相對TinyXml有了明顯的效率提升還是我在RapidXml的使用上有問題,后面需要再仔細調查RapidXml的接口使用方法。 在我自己初步的使用來看,我覺得 RapidXml 的接口并有 Qt 和 TinyXml2 那么簡單易用,所以在文件大小不大或對效率要求不是很極限的情況下,使用 TinyXml2 可能會獲得開發效率和運行效率的雙贏。

再來看一下windows下的運行結果: windows_rapid_reslut 依然不是很穩定,所以只做參考。

總結

統計的時間如下(LINUX):

解析器 消耗時間(ms) 效率倍數(相對Qt)
Qt-QDomDocument 25.85 1
TinyXml2 6.64 3.89
RapidXml 2.71 9.54

工作以來基本上都是在Qt下開發,深切體會到Qt的接口封裝很完善易用,但不可避免的犧牲了一些效率(雖然沒想到效率降低了這么多),相對的,tinyxml2在接口非常相似的同時,效率也有明顯的提升(接近4倍),所以目前xml的解析還是推薦TinyXml2。后面我會繼續仔細研究TinyXml2和RapidXml的使用方法,看是否可以真正將RapidXml的性能發揮出來!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 盐津县| 廉江市| 和田县| 东乡县| 偃师市| 洛浦县| 德格县| 谢通门县| 龙川县| 英吉沙县| 南昌县| 潜江市| 吴江市| 长武县| 项城市| 吉林省| 昌吉市| 公安县| 城口县| 吴桥县| 万载县| 建德市| 麻城市| 洮南市| 广昌县| 克山县| 焉耆| 琼结县| 奉节县| 远安县| 兴安盟| 唐山市| 库伦旗| 新宾| 庄浪县| 井研县| 兰州市| 临泽县| 贵德县| 泽普县| 屏东市|