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 23 using 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) \ 40 void \ 41 TMessageSpeedTest::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 58 MESSAGE_SPEED_TEST_CREATE(5, Int32, "int32", int32 value = i); 59 MESSAGE_SPEED_TEST_CREATE(50, Int32, "int32", int32 value = i); 60 MESSAGE_SPEED_TEST_CREATE(500, Int32, "int32", int32 value = i); 61 MESSAGE_SPEED_TEST_CREATE(5000, Int32, "int32", int32 value = i); 62 63 MESSAGE_SPEED_TEST_CREATE(5, String, "BString", BString value = "item"; value << i); 64 MESSAGE_SPEED_TEST_CREATE(50, String, "BString", BString value = "item"; value << i); 65 MESSAGE_SPEED_TEST_CREATE(500, String, "BString", BString value = "item"; value << i); 66 MESSAGE_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) \ 72 void \ 73 TMessageSpeedTest::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 97 MESSAGE_SPEED_TEST_LOOKUP(5, Int32); 98 MESSAGE_SPEED_TEST_LOOKUP(50, Int32); 99 MESSAGE_SPEED_TEST_LOOKUP(500, Int32); 100 MESSAGE_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) \ 106 void \ 107 TMessageSpeedTest::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 131 MESSAGE_SPEED_TEST_READ(5, Int32, "int32", int32 value = i, int32 value); 132 MESSAGE_SPEED_TEST_READ(50, Int32, "int32", int32 value = i, int32 value); 133 MESSAGE_SPEED_TEST_READ(500, Int32, "int32", int32 value = i, int32 value); 134 MESSAGE_SPEED_TEST_READ(5000, Int32, "int32", int32 value = i, int32 value); 135 136 MESSAGE_SPEED_TEST_READ(5, String, "BString", BString value = "item"; value << i, BString value); 137 MESSAGE_SPEED_TEST_READ(50, String, "BString", BString value = "item"; value << i, BString value); 138 MESSAGE_SPEED_TEST_READ(500, String, "BString", BString value = "item"; value << i, BString value); 139 MESSAGE_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) \ 145 void \ 146 TMessageSpeedTest::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 172 MESSAGE_SPEED_TEST_FLATTEN(5, Int32, "int32", int32 value = i); 173 MESSAGE_SPEED_TEST_FLATTEN(50, Int32, "int32", int32 value = i); 174 MESSAGE_SPEED_TEST_FLATTEN(500, Int32, "int32", int32 value = i); 175 MESSAGE_SPEED_TEST_FLATTEN(5000, Int32, "int32", int32 value = i); 176 177 MESSAGE_SPEED_TEST_FLATTEN(5, String, "BString", BString value = "item"; value << i); 178 MESSAGE_SPEED_TEST_FLATTEN(50, String, "BString", BString value = "item"; value << i); 179 MESSAGE_SPEED_TEST_FLATTEN(500, String, "BString", BString value = "item"; value << i); 180 MESSAGE_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) \ 186 void \ 187 TMessageSpeedTest::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 215 MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(5, Int32, "int32", int32 value = i); 216 MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(50, Int32, "int32", int32 value = i); 217 MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(500, Int32, "int32", int32 value = i); 218 MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(5000, Int32, "int32", int32 value = i); 219 220 MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(5, String, "BString", BString value = "item"; value << i); 221 MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(50, String, "BString", BString value = "item"; value << i); 222 MESSAGE_SPEED_TEST_FLATTEN_INDIVIDUAL(500, String, "BString", BString value = "item"; value << i); 223 MESSAGE_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) \ 229 void \ 230 TMessageSpeedTest::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 257 MESSAGE_SPEED_TEST_UNFLATTEN(5, Int32, "int32"); 258 MESSAGE_SPEED_TEST_UNFLATTEN(50, Int32, "int32"); 259 MESSAGE_SPEED_TEST_UNFLATTEN(500, Int32, "int32"); 260 MESSAGE_SPEED_TEST_UNFLATTEN(5000, Int32, "int32"); 261 262 MESSAGE_SPEED_TEST_UNFLATTEN(5, String, "BString"); 263 MESSAGE_SPEED_TEST_UNFLATTEN(50, String, "BString"); 264 MESSAGE_SPEED_TEST_UNFLATTEN(500, String, "BString"); 265 MESSAGE_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) \ 271 void \ 272 TMessageSpeedTest::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 299 MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(5, Int32, "int32"); 300 MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(50, Int32, "int32"); 301 MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(500, Int32, "int32"); 302 MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(5000, Int32, "int32"); 303 304 MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(5, String, "BString"); 305 MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(50, String, "BString"); 306 MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(500, String, "BString"); 307 MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL(5000, String, "BString"); 308 309 #undef MESSAGE_SPEED_TEST_UNFLATTEN_INDIVIDUAL 310 311 312 TestSuite* 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