C++Xml解析的效率比较(QtTinyXml2RapidXmlPugiXml)
C++Xml 解析的效率⽐较(QtTinyXml2RapidXmlPugiXml )
C++ Xml 解析的效率⽐较(Qt/TinyXml2/RapidXml/PugiXml )
通常我们在⼀些软件的初始化或者保存配置时都会遇到对XML⽂件的操作,包括读写xml⽂件,解析内容等等。在我的⼯作中就遇到了这么⼀个问题,就是在ARM平台下Qt解析xml⽂件⾮常的慢,最初怀疑是我的操作有问题或者是ARM平台下的⽂件操作本⾝就很慢,于是就开始调查到底是哪⾥的效率问题,下⾯是⼀些测试分享给⼤家。
问题背景
下⾯⼀段代码是前⾯提到的运⾏效率低的⼀段代码:
起初以为是⽂件打开和关闭耗时太多,所以在⽂件open和close函数前后都获取了系统时间来测试了函数消耗时间,结果是耗时很短,反⽽是 doc.setContent  耗费了⾮常长的时间,这才发现原来是Qt获取XML⽂件内容且Dom模型结构花费了太多时间,所以我们开始寻求效率更⾼的解决⽅案。
测试环境Windows: system:windows 10 cpu: intel core-i5-5200u @2.2GHz IDE: visual studio 2010 compiler: VC10Linux: 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
⽤来测试的⽂件名为 l,⼤⼩为245Kb,共1561⾏,⼤部分内容为中⽂
⽐较项有 , QDomDocument,因为从接⼝来看这两者的操作⽅式很类似,后⾯我会加⼊其它的xml解析库的⽐较,如 等。
Qt - QDomDocument
下⾯是利⽤Qt中的xml⽀持来读取⽂件内容的源代码:QString filename = "...";QFile file( filename );//< step1 open file if ( !file.open(QIODevice::ReadOnly) ){    qDebug() << "failed in opening file!";    return  false ;}//< step2 read file content QDomDocument 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!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <QtCore/QCoreApplication>#include <qdom.h>#include <QFile>
1
2
3
4
#include <QFile>#include <QIODevice>#include <iostream>#ifdef Q_OS_WIN # include <Windows.
h>#else # include <sys/time.h>#endif using  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:/l" );    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/l" );    QDomDocument doc;    double  timeuse = 0.;    double  timeAverage = 0.;
4
党在我心中手抄报内容
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
世界之最
你会爱我到什么时候56
57
58
59
60
61
62
63
64
65
66
67
68
69
下⾯来看看windows下的运⾏结果:
当时我的反应是 WTF?? 为什么同⼀个函数读同⼀个⽂件⼗次会有这么⼤的差异所以我才会在⽂件打开和关闭时分别都加了延时,希望避免⽂件开关的过程对这个函数产⽣的影响,结果依然没有解决这个问题,这个问题希望有⼤神帮我解答⼀下!    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();}
69
70
电压低电脑自动关机
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
那下⾯我们来看linux下的运⾏结果:
显然,linux下这个时间相对的稳定可信,所以我们后⾯的测试也只要以linux下的时间作为参考。
TinyXml-2
下⾯我们来看利⽤tinyxml2实现读取的源代码:#include <iostream>#include "tinyxml2.h"#ifdef _WIN32#include <Windows.h>#else #include <sys/time.h>#endif using  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/l" ) )        {            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);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
每当我走过老师窗前歌词16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
接下来先看linux下的运⾏结果(windows下的运⾏结果已经没有太多参考价值了):
linux下的表现依然很稳定,这⾥我们可以得出⼀个很明显的结论,tinyxml的处理效率要⽐QDomDocument的处理效率⾼很多(这⾥的数据⼤致是4倍,但不包括对于xml⽂件内部信息的处理的其他函数接⼝的调⽤)。
虽然没什么参考价值,但还是看⼀下windows下的测试结果:
这⾥效率也明显的⽐Windows Qt提升很多,⽽且执⾏时间也相对稳定了⼀,所以前⼀个测试中运⾏时间⼗分不稳定的情况暂定为Qt本⾝实现的问题,具体是什么问题或者在⾼版本的Qt⾥⾯是否已解决尚⽆答案。
RapidXml
注:RapidXml版本: 1.13
在的介绍中可以看到它和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在内容解析时的效率表现,下⾯是源代码:    QueryPerformanceFrequency(&nFreq);    tinyxml2::XMLDocument doc;    for ( int  i = 0; i < TEST_TI
MES; ++i )    {        QueryPerformanceCounter(&nStartTime);        if ( XML_SUCCESS != doc.LoadFile( "D:/l" ) )        {            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;}
47
48
49
50
51
52
商业计划书
53
54
55
56
57
58
59
60
61
62
63
64
65
66

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。