1 // file : examples/performance/expat.cxx
2 // license : not copyrighted - public domain
3
4 #include <iostream>
5 #include <fstream>
6
7 #include <expat.h>
8
9 #include "time.hxx"
10
11 using namespace std;
12
13 const unsigned long iterations = 1000;
14
15 unsigned long start_count;
16 unsigned long end_count;
17
18 void XMLCALL
start_element(void * data,const XML_Char * ns_name,const XML_Char ** atts)19 start_element (void* data, const XML_Char* ns_name, const XML_Char** atts)
20 {
21 start_count++;
22 }
23
24 void XMLCALL
end_element(void * data,const XML_Char * ns_name)25 end_element (void* data, const XML_Char* ns_name)
26 {
27 end_count++;
28 }
29
30 void XMLCALL
characters(void * data,const XML_Char * s,int n)31 characters (void* data, const XML_Char* s, int n)
32 {
33 }
34
35 int
main(int argc,char * argv[])36 main (int argc, char* argv[])
37 {
38 if (argc != 2)
39 {
40 cerr << "usage: " << argv[0] << " <xml-file>" << endl;
41 return 1;
42 }
43
44 try
45 {
46 ifstream ifs;
47 ifs.exceptions (ios_base::failbit);
48 ifs.open (argv[1], ios::in | ios::ate);
49
50 size_t size (ifs.tellg ());
51 ifs.seekg (0, ios::beg);
52
53 char* buf = new char[size];
54 ifs.read (buf, size);
55
56 cerr << " document size: " << size << " bytes" << endl;
57
58 // Warmup.
59 //
60 bool failed (false);
61 for (unsigned long i (0); !failed && i < 10; ++i)
62 {
63 start_count = 0;
64 end_count = 0;
65
66 XML_Parser p (XML_ParserCreateNS (0, ' '));
67 XML_SetStartElementHandler (p, start_element);
68 XML_SetEndElementHandler (p, end_element);
69 XML_SetCharacterDataHandler (p, characters);
70 XML_Parse (p, buf, size, 1);
71 XML_ParserFree (p);
72
73 if (start_count != end_count)
74 failed = true;
75 }
76
77 if (failed)
78 {
79 cerr << "failed" << endl;
80 return 1;
81 }
82
83 cerr << " elements: " << start_count << endl;
84
85 os::time start;
86
87 for (unsigned long i (0); !failed && i < 1000; ++i)
88 {
89 start_count = 0;
90 end_count = 0;
91
92 XML_Parser p (XML_ParserCreateNS (0, ' '));
93 XML_SetStartElementHandler (p, start_element);
94 XML_SetEndElementHandler (p, end_element);
95 XML_SetCharacterDataHandler (p, characters);
96 XML_Parse (p, buf, size, 1);
97 XML_ParserFree (p);
98
99 if (start_count != end_count)
100 failed = true;
101 }
102
103 os::time end;
104 delete[] buf;
105
106 if (failed)
107 {
108 cerr << "failed" << endl;
109 return 1;
110 }
111
112 os::time time (end - start);
113 double ms (time.sec () * 1000000ULL + time.nsec () / 1000ULL);
114
115 cerr << " time: " << time << " sec" << endl;
116
117 // Calculate throughput in documents/sec.
118 //
119 double tpd ((iterations / ms) * 1000000);
120 cerr << " throughput: " << tpd << " documents/sec" << endl;
121
122 // Calculate throughput in MBytes/sec.
123 //
124 double tpb (((size * iterations) / ms) * 1000000/(1024*1024));
125 cerr << " throughput: " << tpb << " MBytes/sec" << endl;
126 }
127 catch (ios_base::failure const&)
128 {
129 cerr << "io failure" << endl;
130 return 1;
131 }
132 }
133