1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <iostream>
24 #define _USE_MATH_DEFINES
25 #include <math.h>
26 #include <memory>
27 #include "thrift/protocol/TBinaryProtocol.h"
28 #include "thrift/transport/TBufferTransports.h"
29 #include "gen-cpp/DebugProtoTest_types.h"
30 
31 #ifdef HAVE_SYS_TIME_H
32 #include <sys/time.h>
33 #endif
34 
35 class Timer {
36 public:
37   timeval vStart;
38 
Timer()39   Timer() { THRIFT_GETTIMEOFDAY(&vStart, nullptr); }
start()40   void start() { THRIFT_GETTIMEOFDAY(&vStart, nullptr); }
41 
frame()42   double frame() {
43     timeval vEnd;
44     THRIFT_GETTIMEOFDAY(&vEnd, nullptr);
45     double dstart = vStart.tv_sec + ((double)vStart.tv_usec / 1000000.0);
46     double dend = vEnd.tv_sec + ((double)vEnd.tv_usec / 1000000.0);
47     return dend - dstart;
48   }
49 };
50 
main()51 int main() {
52   using namespace thrift::test::debug;
53   using namespace apache::thrift::transport;
54   using namespace apache::thrift::protocol;
55   using std::cout;
56   using std::endl;
57 
58   OneOfEach ooe;
59   ooe.im_true = true;
60   ooe.im_false = false;
61   ooe.a_bite = 0x7f;
62   ooe.integer16 = 27000;
63   ooe.integer32 = 1 << 24;
64   ooe.integer64 = (uint64_t)6000 * 1000 * 1000;
65   ooe.double_precision = M_PI;
66   ooe.some_characters = "JSON THIS! \"\1";
67   ooe.zomg_unicode = "\xd7\n\a\t";
68   ooe.base64 = "\1\2\3\255";
69 
70   int num = 100000;
71   std::shared_ptr<TMemoryBuffer> buf(new TMemoryBuffer(num*1000));
72 
73   uint8_t* data = nullptr;
74   uint32_t datasize = 0;
75 
76   {
77     buf->resetBuffer();
78     TBinaryProtocolT<TMemoryBuffer> prot(buf);
79     double elapsed = 0.0;
80     Timer timer;
81 
82     for (int i = 0; i < num; i++) {
83       ooe.write(&prot);
84     }
85     elapsed = timer.frame();
86     cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << endl;
87   }
88 
89   buf->getBuffer(&data, &datasize);
90 
91   {
92     std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
93     TBinaryProtocolT<TMemoryBuffer> prot(buf2);
94     OneOfEach ooe2;
95     double elapsed = 0.0;
96     Timer timer;
97 
98     for (int i = 0; i < num; i++) {
99       ooe2.read(&prot);
100     }
101     elapsed = timer.frame();
102     cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << endl;
103   }
104 
105   {
106     buf->resetBuffer();
107     TBinaryProtocolT<TMemoryBuffer, TNetworkLittleEndian> prot(buf);
108     double elapsed = 0.0;
109     Timer timer;
110 
111     for (int i = 0; i < num; i++) {
112       ooe.write(&prot);
113     }
114     elapsed = timer.frame();
115     cout << "Write little endian: " << num / (1000 * elapsed) << " kHz" << endl;
116   }
117 
118   {
119     OneOfEach ooe2;
120     std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
121     TBinaryProtocolT<TMemoryBuffer, TNetworkLittleEndian> prot(buf2);
122     double elapsed = 0.0;
123     Timer timer;
124 
125     for (int i = 0; i < num; i++) {
126       ooe2.read(&prot);
127     }
128     elapsed = timer.frame();
129     cout << " Read little endian: " << num / (1000 * elapsed) << " kHz" << endl;
130   }
131 
132   {
133     buf->resetBuffer();
134     TBinaryProtocolT<TMemoryBuffer> prot(buf);
135     double elapsed = 0.0;
136     Timer timer;
137 
138     for (int i = 0; i < num; i++) {
139       ooe.write(&prot);
140     }
141     elapsed = timer.frame();
142     cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << endl;
143   }
144 
145   {
146     std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
147     TBinaryProtocolT<TMemoryBuffer> prot(buf2);
148     OneOfEach ooe2;
149     double elapsed = 0.0;
150     Timer timer;
151 
152     for (int i = 0; i < num; i++) {
153       ooe2.read(&prot);
154     }
155     elapsed = timer.frame();
156     cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << endl;
157   }
158 
159 
160   data = nullptr;
161   datasize = 0;
162   num = 10000000;
163 
164   ListDoublePerf listDoublePerf;
165   listDoublePerf.field.reserve(num);
166   for (int x = 0; x < num; ++x)
167     listDoublePerf.field.push_back(double(x));
168 
169   buf.reset(new TMemoryBuffer(num * 100));
170 
171   {
172     buf->resetBuffer();
173     TBinaryProtocolT<TMemoryBuffer> prot(buf);
174     double elapsed = 0.0;
175     Timer timer;
176 
177     listDoublePerf.write(&prot);
178     elapsed = timer.frame();
179     cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << endl;
180   }
181 
182   buf->getBuffer(&data, &datasize);
183 
184   {
185     std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
186     TBinaryProtocolT<TMemoryBuffer> prot(buf2);
187     ListDoublePerf listDoublePerf2;
188     double elapsed = 0.0;
189     Timer timer;
190 
191     listDoublePerf2.read(&prot);
192     elapsed = timer.frame();
193     cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << endl;
194   }
195 
196   {
197     buf->resetBuffer();
198     TBinaryProtocolT<TMemoryBuffer, TNetworkLittleEndian> prot(buf);
199     double elapsed = 0.0;
200     Timer timer;
201 
202     listDoublePerf.write(&prot);
203     elapsed = timer.frame();
204     cout << "Double write little endian: " << num / (1000 * elapsed) << " kHz" << endl;
205   }
206 
207   {
208     ListDoublePerf listDoublePerf2;
209     std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
210     TBinaryProtocolT<TMemoryBuffer, TNetworkLittleEndian> prot(buf2);
211     double elapsed = 0.0;
212     Timer timer;
213 
214     listDoublePerf2.read(&prot);
215     elapsed = timer.frame();
216     cout << " Double read little endian: " << num / (1000 * elapsed) << " kHz" << endl;
217   }
218 
219   {
220     buf->resetBuffer();
221     TBinaryProtocolT<TMemoryBuffer> prot(buf);
222     double elapsed = 0.0;
223     Timer timer;
224 
225     listDoublePerf.write(&prot);
226     elapsed = timer.frame();
227     cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << endl;
228   }
229 
230   {
231     std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
232     TBinaryProtocolT<TMemoryBuffer> prot(buf2);
233     ListDoublePerf listDoublePerf2;
234     double elapsed = 0.0;
235     Timer timer;
236 
237     listDoublePerf2.read(&prot);
238     elapsed = timer.frame();
239     cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << endl;
240   }
241 
242 
243   return 0;
244 }
245