1/*
2 * Copyright 2005, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Michael Lotz <mmlr@mlotz.ch>
7 *		Olivier Milla <methedras at online dot fr>
8 */
9
10#include <iostream>
11#include <stdio.h>
12#include <stdlib.h>
13#include <time.h>
14
15#include <Entry.h>
16#include <File.h>
17#include <Message.h>
18#include <String.h>
19
20#include "MessageSpeedTest.h"
21
22
23using namespace std;
24
25
26#define LOG_TO_FILE
27#ifdef LOG_TO_FILE
28#define LOG(function, time)													\
29	{																		\
30		FILE *logfile = fopen("/boot/home/Desktop/messagespeed.log", "a");	\
31		fprintf(logfile, "%s:\t%lld\n", function, time);					\
32		fclose(logfile);													\
33	}
34#else
35#define LOG(function, time) /* empty */
36#endif
37
38
39#define MESSAGE_SPEED_TEST_CREATE(count, type, typeName, createValue)		\
40void																		\
41TMessageSpeedTest::MessageSpeedTestCreate##count##type()					\
42{																			\
43	BMessage message;														\
44	bigtime_t length = 0;													\
45																			\
46	for (int32 i = 0; i < count; i++) {										\
47		createValue;														\
48		bigtime_t stamp = real_time_clock_usecs();							\
49		message.Add##type("data", value);									\
50		length += (real_time_clock_usecs() - stamp);						\
51	}																		\
52																			\
53	cout << "Time to add " << count << " " << typeName						\
54		<< " in a message = " << length << "usec" << endl;					\
55	LOG(__PRETTY_FUNCTION__, length);										\
56}
57
58MESSAGE_SPEED_TEST_CREATE(5, Int32, "int32", int32 value = i);
59MESSAGE_SPEED_TEST_CREATE(50, Int32, "int32", int32 value = i);
60MESSAGE_SPEED_TEST_CREATE(500, Int32, "int32", int32 value = i);
61MESSAGE_SPEED_TEST_CREATE(5000, Int32, "int32", int32 value = i);
62
63MESSAGE_SPEED_TEST_CREATE(5, String, "BString", BString value = "item"; value << i);
64MESSAGE_SPEED_TEST_CREATE(50, String, "BString", BString value = "item"; value << i);
65MESSAGE_SPEED_TEST_CREATE(500, String, "BString", BString value = "item"; value << i);
66MESSAGE_SPEED_TEST_CREATE(5000, String, "BString", BString value = "item"; value << i);
67
68#undef MESSAGE_SPEED_TEST_CREATE
69
70
71#define MESSAGE_SPEED_TEST_LOOKUP(count, type)								\
72void																		\
73TMessageSpeedTest::MessageSpeedTestLookup##count##type()					\
74{																			\
75	srand(time(NULL));														\
76	BMessage message;														\
77																			\
78	for (int32 i = 0; i < count; i++) {										\
79		BString string;														\
80		string << i;														\
81		message.AddInt32(string.String(), i);								\
82	}																		\
83																			\
84	BString search;															\
85	search << rand() % count;												\
86	const char *string = search.String();									\
87	int32 res;																\
88																			\
89	bigtime_t stamp = real_time_clock_usecs();								\
90	message.FindInt32(string, &res);										\
91	bigtime_t length = real_time_clock_usecs() - stamp;						\
92	cout << "Time to find a data in a message containing " << count			\
93		<< " items = " << length << "usec" << endl;							\
94	LOG(__PRETTY_FUNCTION__, length);										\
95}
96
97MESSAGE_SPEED_TEST_LOOKUP(5, Int32);
98MESSAGE_SPEED_TEST_LOOKUP(50, Int32);
99MESSAGE_SPEED_TEST_LOOKUP(500, Int32);
100MESSAGE_SPEED_TEST_LOOKUP(5000, Int32);
101
102#undef MESSAGE_SPEED_TEST_LOOKUP
103
104
105#define MESSAGE_SPEED_TEST_READ(count, type, typeName, createValue, declareValue)	\
106void																		\
107TMessageSpeedTest::MessageSpeedTestRead##count##type()						\
108{																			\
109	srand(time(NULL));														\
110	BMessage message;														\
111																			\
112	for (int32 i = 0; i < count; i++) {										\
113		createValue;														\
114		message.Add##type("data", value);									\
115	}																		\
116																			\
117	declareValue;															\
118	bigtime_t length = 0;													\
119	for (int32 i = 0; i < count; i++) {										\
120		bigtime_t stamp = real_time_clock_usecs();							\
121		message.Find##type("data", i, &value);								\
122		length += (real_time_clock_usecs() - stamp);						\
123	}																		\
124																			\
125	cout << "Time to retrieve " << count << " " << typeName					\
126		<< " out of a message = " << length << "usec. Giving "				\
127		<< length / count << "usec per retrieve." << endl;					\
128	LOG(__PRETTY_FUNCTION__, length);										\
129}
130
131MESSAGE_SPEED_TEST_READ(5, Int32, "int32", int32 value = i, int32 value);
132MESSAGE_SPEED_TEST_READ(50, Int32, "int32", int32 value = i, int32 value);
133MESSAGE_SPEED_TEST_READ(500, Int32, "int32", int32 value = i, int32 value);
134MESSAGE_SPEED_TEST_READ(5000, Int32, "int32", int32 value = i, int32 value);
135
136MESSAGE_SPEED_TEST_READ(5, String, "BString", BString value = "item"; value << i, BString value);
137MESSAGE_SPEED_TEST_READ(50, String, "BString", BString value = "item"; value << i, BString value);
138MESSAGE_SPEED_TEST_READ(500, String, "BString", BString value = "item"; value << i, BString value);
139MESSAGE_SPEED_TEST_READ(5000, String, "BString", BString value = "item"; value << i, BString value);
140
141#undef MESSAGE_SPEED_TEST_READ
142
143
144#define MESSAGE_SPEED_TEST_FLATTEN(count, type, typeName, createValue)		\
145void																		\
146TMessageSpeedTest::MessageSpeedTestFlatten##count##type()					\
147{																			\
148	BMessage message;														\
149																			\
150	for (int32 i = 0; i < count; i++) { 									\
151		createValue;														\
152		message.Add##type("data", value);									\
153	}																		\
154																			\
155	BMallocIO buffer;														\
156	bigtime_t stamp = real_time_clock_usecs();								\
157	message.Flatten(&buffer);												\
158	bigtime_t length = real_time_clock_usecs() - stamp;						\
159																			\
160	BString name = "/tmp/MessageSpeedTestFlatten";							\
161	name << count << typeName;												\
162	BEntry entry(name.String());											\
163	BFile file(&entry, B_READ_WRITE | B_CREATE_FILE);						\
164	file.Write(buffer.Buffer(), buffer.BufferLength());						\
165																			\
166	cout << "Time to flatten a message containing " << count << " "			\
167		<< typeName << " = " << length << "usec. Giving " << length / count	\
168		<< "usec per item." << endl;										\
169	LOG(__PRETTY_FUNCTION__, length);										\
170}
171
172MESSAGE_SPEED_TEST_FLATTEN(5, Int32, "int32", int32 value = i);
173MESSAGE_SPEED_TEST_FLATTEN(50, Int32, "int32", int32 value = i);
174MESSAGE_SPEED_TEST_FLATTEN(500, Int32, "int32", int32 value = i);
175MESSAGE_SPEED_TEST_FLATTEN(5000, Int32, "int32", int32 value = i);
176
177MESSAGE_SPEED_TEST_FLATTEN(5, String, "BString", BString value = "item"; value << i);
178MESSAGE_SPEED_TEST_FLATTEN(50, String, "BString", BString value = "item"; value << i);
179MESSAGE_SPEED_TEST_FLATTEN(500, String, "BString", BString value = "item"; value << i);
180MESSAGE_SPEED_TEST_FLATTEN(5000, String, "BString", BString value = "item"; value << i);
181
182#undef MESSAGE_SPEED_TEST_FLATTEN
183
184
185#define MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(count, type, typeName, createValue)	\
186void																		\
187TMessageSpeedTest::MessageSpeedTestFlattenIndividual##count##type()			\
188{																			\
189	BMessage message;														\
190																			\
191	for (int32 i = 0; i < count; i++) {										\
192		createValue;														\
193		BString name = "data";												\
194		name << i;															\
195		message.Add##type(name.String(), value);							\
196	}																		\
197																			\
198	BMallocIO buffer;														\
199	bigtime_t stamp = real_time_clock_usecs();								\
200	message.Flatten(&buffer);												\
201	bigtime_t length = real_time_clock_usecs() - stamp;						\
202																			\
203	BString name = "/tmp/MessageSpeedTestFlattenIndividual";				\
204	name << count << typeName;												\
205	BEntry entry(name.String());											\
206	BFile file(&entry, B_READ_WRITE | B_CREATE_FILE);						\
207	file.Write(buffer.Buffer(), buffer.BufferLength());						\
208																			\
209	cout << "Time to flatten a message containing " << count				\
210		<< " individual " << typeName << " fields = " << length				\
211		<< "usec. Giving " << length / count << "usec per item." << endl;	\
212	LOG(__PRETTY_FUNCTION__, length);										\
213}
214
215MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(5, Int32, "int32", int32 value = i);
216MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(50, Int32, "int32", int32 value = i);
217MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(500, Int32, "int32", int32 value = i);
218MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(5000, Int32, "int32", int32 value = i);
219
220MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(5, String, "BString", BString value = "item"; value << i);
221MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(50, String, "BString", BString value = "item"; value << i);
222MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(500, String, "BString", BString value = "item"; value << i);
223MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(5000, String, "BString", BString value = "item"; value << i);
224
225#undef MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL
226
227
228#define MESSAGE_SPEED_TEST_UNFLATTEN(count, type, typeName)					\
229void																		\
230TMessageSpeedTest::MessageSpeedTestUnflatten##count##type()					\
231{																			\
232	BString name = "/tmp/MessageSpeedTestFlatten";							\
233	name << count << typeName;												\
234	BEntry entry(name.String());											\
235	BFile file(&entry, B_READ_ONLY);										\
236																			\
237	off_t size = 0;															\
238	file.GetSize(&size);													\
239	char *buffer = (char *)malloc(size);									\
240	file.Read(buffer, size);												\
241	BMemoryIO stream(buffer, size);											\
242																			\
243	BMessage rebuilt;														\
244	bigtime_t stamp = real_time_clock_usecs();								\
245	rebuilt.Unflatten(&stream);												\
246	bigtime_t length = real_time_clock_usecs() - stamp;						\
247																			\
248	cout << "Time to unflatten a message containing " << count << " "		\
249		<< typeName	<< " = " << length << "usec. Giving " << length / count	\
250		<< "usec per item." << endl;										\
251	LOG(__PRETTY_FUNCTION__, length);										\
252																			\
253	file.Unset();															\
254	entry.Remove();															\
255}
256
257MESSAGE_SPEED_TEST_UNFLATTEN(5, Int32, "int32");
258MESSAGE_SPEED_TEST_UNFLATTEN(50, Int32, "int32");
259MESSAGE_SPEED_TEST_UNFLATTEN(500, Int32, "int32");
260MESSAGE_SPEED_TEST_UNFLATTEN(5000, Int32, "int32");
261
262MESSAGE_SPEED_TEST_UNFLATTEN(5, String, "BString");
263MESSAGE_SPEED_TEST_UNFLATTEN(50, String, "BString");
264MESSAGE_SPEED_TEST_UNFLATTEN(500, String, "BString");
265MESSAGE_SPEED_TEST_UNFLATTEN(5000, String, "BString");
266
267#undef MESSAGE_SPEED_TEST_UNFLATTEN
268
269
270#define MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(count, type, typeName)		\
271void																		\
272TMessageSpeedTest::MessageSpeedTestUnflattenIndividual##count##type()		\
273{																			\
274	BString name = "/tmp/MessageSpeedTestFlattenIndividual";				\
275	name << count << typeName;												\
276	BEntry entry(name.String());											\
277	BFile file(&entry, B_READ_ONLY);										\
278																			\
279	off_t size = 0;															\
280	file.GetSize(&size);													\
281	char *buffer = (char *)malloc(size);									\
282	file.Read(buffer, size);												\
283	BMemoryIO stream(buffer, size);											\
284																			\
285	BMessage rebuilt;														\
286	bigtime_t stamp = real_time_clock_usecs();								\
287	rebuilt.Unflatten(&stream);												\
288	bigtime_t length = real_time_clock_usecs() - stamp;						\
289																			\
290	cout << "Time to unflatten a message containing " << count				\
291		<< " individual " << typeName << " fields = " << length				\
292		<< "usec. Giving " << length / count << "usec per item." << endl;	\
293	LOG(__PRETTY_FUNCTION__, length);										\
294																			\
295	file.Unset();															\
296	entry.Remove();															\
297}
298
299MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(5, Int32, "int32");
300MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(50, Int32, "int32");
301MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(500, Int32, "int32");
302MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(5000, Int32, "int32");
303
304MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(5, String, "BString");
305MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(50, String, "BString");
306MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(500, String, "BString");
307MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(5000, String, "BString");
308
309#undef MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL
310
311
312TestSuite* TMessageSpeedTest::Suite()
313{
314	TestSuite* suite = new TestSuite("BMessage::Test of Performance");
315
316	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestCreate5Int32);
317	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestCreate50Int32);
318	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestCreate500Int32);
319	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestCreate5000Int32);
320
321	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestCreate5String);
322	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestCreate50String);
323	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestCreate500String);
324	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestCreate5000String);
325
326	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestLookup5Int32);
327	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestLookup50Int32);
328	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestLookup500Int32);
329	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestLookup5000Int32);
330
331	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestRead5Int32);
332	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestRead50Int32);
333	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestRead500Int32);
334	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestRead5000Int32);
335
336	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestRead5String);
337	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestRead50String);
338	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestRead500String);
339	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestRead5000String);
340
341	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlatten5Int32);
342	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlatten50Int32);
343	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlatten500Int32);
344	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlatten5000Int32);
345
346	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlatten5String);
347	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlatten50String);
348	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlatten500String);
349	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlatten5000String);
350
351	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlattenIndividual5Int32);
352	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlattenIndividual50Int32);
353	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlattenIndividual500Int32);
354	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlattenIndividual5000Int32);
355
356	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlattenIndividual5String);
357	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlattenIndividual50String);
358	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlattenIndividual500String);
359	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestFlattenIndividual5000String);
360
361	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflatten5Int32);
362	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflatten50Int32);
363	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflatten500Int32);
364	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflatten5000Int32);
365
366	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflatten5String);
367	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflatten50String);
368	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflatten500String);
369	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflatten5000String);
370
371	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflattenIndividual5Int32);
372	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflattenIndividual50Int32);
373	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflattenIndividual500Int32);
374	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflattenIndividual5000Int32);
375
376	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflattenIndividual5String);
377	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflattenIndividual50String);
378	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflattenIndividual500String);
379	ADD_TEST4(BMessage, suite, TMessageSpeedTest, MessageSpeedTestUnflattenIndividual5000String);
380
381	return suite;
382}
383