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