hashTest.cpp 12.7 KB
Newer Older
H
hjxilinx 已提交
1 2 3 4
#include <gtest/gtest.h>
#include <limits.h>
#include <iostream>

5
#include "os.h"
H
Hongze Cheng 已提交
6
#include "taos.h"
7
#include "taosdef.h"
D
dapan1121 已提交
8
#include "thash.h"
H
hjxilinx 已提交
9 10

namespace {
D
dapan1121 已提交
11 12

typedef struct TESTSTRUCT {
H
Hongze Cheng 已提交
13 14
  char* p;
} TESTSTRUCT;
D
dapan1121 已提交
15

H
hjxilinx 已提交
16 17
// the simple test code for basic operations
void simpleTest() {
H
Hongze Cheng 已提交
18 19
  SHashObj* hashTable =
      (SHashObj*)taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
H
hjxilinx 已提交
20
  ASSERT_EQ(taosHashGetSize(hashTable), 0);
H
Hongze Cheng 已提交
21

H
hjxilinx 已提交
22
  // put 400 elements in the hash table
H
Hongze Cheng 已提交
23 24
  for (int32_t i = -200; i < 200; ++i) {
    taosHashPut(hashTable, (const char*)&i, sizeof(int32_t), (char*)&i, sizeof(int32_t));
H
hjxilinx 已提交
25
  }
H
Hongze Cheng 已提交
26

H
hjxilinx 已提交
27
  ASSERT_EQ(taosHashGetSize(hashTable), 400);
H
Hongze Cheng 已提交
28 29 30

  for (int32_t i = 0; i < 200; ++i) {
    char* p = (char*)taosHashGet(hashTable, (const char*)&i, sizeof(int32_t));
H
hjxilinx 已提交
31 32 33
    ASSERT_TRUE(p != nullptr);
    ASSERT_EQ(*reinterpret_cast<int32_t*>(p), i);
  }
H
Hongze Cheng 已提交
34 35 36

  for (int32_t i = 1000; i < 2000; ++i) {
    taosHashRemove(hashTable, (const char*)&i, sizeof(int32_t));
H
hjxilinx 已提交
37
  }
H
Hongze Cheng 已提交
38

H
hjxilinx 已提交
39
  ASSERT_EQ(taosHashGetSize(hashTable), 400);
H
Hongze Cheng 已提交
40 41 42

  for (int32_t i = 0; i < 100; ++i) {
    taosHashRemove(hashTable, (const char*)&i, sizeof(int32_t));
H
hjxilinx 已提交
43
  }
H
Hongze Cheng 已提交
44

H
hjxilinx 已提交
45
  ASSERT_EQ(taosHashGetSize(hashTable), 300);
H
Hongze Cheng 已提交
46 47 48

  for (int32_t i = 100; i < 150; ++i) {
    taosHashRemove(hashTable, (const char*)&i, sizeof(int32_t));
H
hjxilinx 已提交
49
  }
H
Hongze Cheng 已提交
50

H
hjxilinx 已提交
51 52 53 54 55
  ASSERT_EQ(taosHashGetSize(hashTable), 250);
  taosHashCleanup(hashTable);
}

void stringKeyTest() {
H
Hongze Cheng 已提交
56 57
  auto* hashTable =
      (SHashObj*)taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
H
hjxilinx 已提交
58
  ASSERT_EQ(taosHashGetSize(hashTable), 0);
H
Hongze Cheng 已提交
59

H
hjxilinx 已提交
60
  char key[128] = {0};
H
Hongze Cheng 已提交
61

H
hjxilinx 已提交
62
  // put 200 elements in the hash table
H
Hongze Cheng 已提交
63
  for (int32_t i = 0; i < 1000; ++i) {
H
hjxilinx 已提交
64
    int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
H
Hongze Cheng 已提交
65
    taosHashPut(hashTable, key, len, (char*)&i, sizeof(int32_t));
H
hjxilinx 已提交
66
  }
H
Hongze Cheng 已提交
67

H
hjxilinx 已提交
68
  ASSERT_EQ(taosHashGetSize(hashTable), 1000);
H
Hongze Cheng 已提交
69 70

  for (int32_t i = 0; i < 1000; ++i) {
H
hjxilinx 已提交
71
    int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
H
Hongze Cheng 已提交
72 73

    char* p = (char*)taosHashGet(hashTable, key, len);
H
hjxilinx 已提交
74
    ASSERT_TRUE(p != nullptr);
H
Hongze Cheng 已提交
75

H
hjxilinx 已提交
76 77
    ASSERT_EQ(*reinterpret_cast<int32_t*>(p), i);
  }
H
Hongze Cheng 已提交
78 79

  for (int32_t i = 500; i < 1000; ++i) {
H
hjxilinx 已提交
80
    int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
H
Hongze Cheng 已提交
81

H
hjxilinx 已提交
82 83
    taosHashRemove(hashTable, key, len);
  }
H
Hongze Cheng 已提交
84

H
hjxilinx 已提交
85
  ASSERT_EQ(taosHashGetSize(hashTable), 500);
H
Hongze Cheng 已提交
86 87

  for (int32_t i = 0; i < 499; ++i) {
H
hjxilinx 已提交
88
    int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
H
Hongze Cheng 已提交
89

H
hjxilinx 已提交
90 91
    taosHashRemove(hashTable, key, len);
  }
H
Hongze Cheng 已提交
92

H
hjxilinx 已提交
93
  ASSERT_EQ(taosHashGetSize(hashTable), 1);
H
Hongze Cheng 已提交
94

H
hjxilinx 已提交
95 96 97
  taosHashCleanup(hashTable);
}

H
Hongze Cheng 已提交
98
void functionTest() {}
H
hjxilinx 已提交
99 100 101 102 103 104

/**
 * evaluate the performance issue, by add 10million elements in to hash table in
 * a single threads situation
 */
void noLockPerformanceTest() {
H
Hongze Cheng 已提交
105 106
  auto* hashTable =
      (SHashObj*)taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
H
hjxilinx 已提交
107
  ASSERT_EQ(taosHashGetSize(hashTable), 0);
H
Hongze Cheng 已提交
108 109

  char    key[128] = {0};
110
  int32_t num = 5000;
H
Hongze Cheng 已提交
111

H
hjxilinx 已提交
112
  int64_t st = taosGetTimestampUs();
H
Hongze Cheng 已提交
113

H
hjxilinx 已提交
114
  // put 10M elements in the hash table
H
Hongze Cheng 已提交
115
  for (int32_t i = 0; i < num; ++i) {
H
hjxilinx 已提交
116
    int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
H
Hongze Cheng 已提交
117
    taosHashPut(hashTable, key, len, (char*)&i, sizeof(int32_t));
H
hjxilinx 已提交
118
  }
H
Hongze Cheng 已提交
119

H
hjxilinx 已提交
120
  ASSERT_EQ(taosHashGetSize(hashTable), num);
H
Hongze Cheng 已提交
121

H
hjxilinx 已提交
122
  int64_t et = taosGetTimestampUs();
H
Hongze Cheng 已提交
123 124
  printf("Elpased time:%" PRId64 " us to add %d elements, avg cost:%lf us\n", et - st, num, (et - st) / (double)num);

H
hjxilinx 已提交
125
  st = taosGetTimestampUs();
H
Hongze Cheng 已提交
126
  for (int32_t i = 0; i < num; ++i) {
H
hjxilinx 已提交
127
    int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
H
Hongze Cheng 已提交
128
    char*   p = (char*)taosHashGet(hashTable, key, len);
H
hjxilinx 已提交
129
    ASSERT_TRUE(p != nullptr);
H
Hongze Cheng 已提交
130

H
hjxilinx 已提交
131 132
    ASSERT_EQ(*reinterpret_cast<int32_t*>(p), i);
  }
H
Hongze Cheng 已提交
133

H
hjxilinx 已提交
134
  et = taosGetTimestampUs();
H
Hongze Cheng 已提交
135 136 137
  printf("Elpased time:%" PRId64 " us to fetch all %d elements, avg cost:%lf us\n", et - st, num,
         (et - st) / (double)num);

H
hjxilinx 已提交
138 139 140 141 142
  printf("The maximum length of overflow linklist in hash table is:%d\n", taosHashGetMaxOverflowLinkLength(hashTable));
  taosHashCleanup(hashTable);
}

void multithreadsTest() {
H
Hongze Cheng 已提交
143
  // todo
H
hjxilinx 已提交
144 145 146
}

// check the function robustness
H
Hongze Cheng 已提交
147
void invalidOperationTest() {}
H
hjxilinx 已提交
148

D
dapan1121 已提交
149
void acquireRleaseTest() {
H
Hongze Cheng 已提交
150 151
  SHashObj* hashTable =
      (SHashObj*)taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
D
dapan1121 已提交
152 153
  ASSERT_EQ(taosHashGetSize(hashTable), 0);

H
Hongze Cheng 已提交
154 155 156 157 158 159 160
  int32_t     key = 2;
  int32_t     code = 0;
  int32_t     num = 0;
  TESTSTRUCT  data = {0};
  const char* str1 = "abcdefg";
  const char* str2 = "aaaaaaa";
  const char* str3 = "123456789";
D
dapan1121 已提交
161

H
Hongze Cheng 已提交
162
  data.p = (char*)taosMemoryMalloc(10);
D
dapan1121 已提交
163 164 165 166 167 168 169 170
  strcpy(data.p, str1);

  code = taosHashPut(hashTable, &key, sizeof(key), &data, sizeof(data));
  ASSERT_EQ(code, 0);

  TESTSTRUCT* pdata = (TESTSTRUCT*)taosHashAcquire(hashTable, &key, sizeof(key));
  ASSERT_TRUE(pdata != nullptr);
  ASSERT_TRUE(strcmp(pdata->p, str1) == 0);
H
Hongze Cheng 已提交
171

D
dapan1121 已提交
172 173 174 175 176 177
  code = taosHashRemove(hashTable, &key, sizeof(key));
  ASSERT_EQ(code, 0);
  ASSERT_TRUE(strcmp(pdata->p, str1) == 0);

  num = taosHashGetSize(hashTable);
  ASSERT_EQ(num, 1);
H
Hongze Cheng 已提交
178

D
dapan1121 已提交
179 180
  strcpy(pdata->p, str3);

H
Hongze Cheng 已提交
181
  data.p = (char*)taosMemoryMalloc(10);
D
dapan1121 已提交
182 183 184 185 186 187 188 189
  strcpy(data.p, str2);
  code = taosHashPut(hashTable, &key, sizeof(key), &data, sizeof(data));
  ASSERT_EQ(code, 0);
  num = taosHashGetSize(hashTable);
  ASSERT_EQ(num, 2);

  printf("%s,expect:%s", pdata->p, str3);
  ASSERT_TRUE(strcmp(pdata->p, str3) == 0);
190

wafwerar's avatar
wafwerar 已提交
191
  taosMemoryFreeClear(pdata->p);
192

D
dapan1121 已提交
193 194 195
  taosHashRelease(hashTable, pdata);
  num = taosHashGetSize(hashTable);
  ASSERT_EQ(num, 1);
196 197

  taosHashCleanup(hashTable);
wafwerar's avatar
wafwerar 已提交
198
  taosMemoryFreeClear(data.p);
D
dapan1121 已提交
199 200
}

D
dapan1121 已提交
201
void perfTest() {
H
Hongze Cheng 已提交
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
  SHashObj* hash1h =
      (SHashObj*)taosHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
  SHashObj* hash1s =
      (SHashObj*)taosHashInit(1000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
  SHashObj* hash10s =
      (SHashObj*)taosHashInit(10000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
  SHashObj* hash100s =
      (SHashObj*)taosHashInit(100000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
  SHashObj* hash1m =
      (SHashObj*)taosHashInit(1000000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
  SHashObj* hash10m =
      (SHashObj*)taosHashInit(10000000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
  SHashObj* hash100m =
      (SHashObj*)taosHashInit(100000000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);

  char* name = (char*)taosMemoryCalloc(50000000, 9);
D
dapan1121 已提交
218
  for (int64_t i = 0; i < 50000000; ++i) {
219
    sprintf(name + i * 9, "t%08" PRId64, i);
D
dapan1121 已提交
220
  }
H
Hongze Cheng 已提交
221

D
dapan1121 已提交
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
  for (int64_t i = 0; i < 50; ++i) {
    taosHashPut(hash1h, name + i * 9, 9, &i, sizeof(i));
  }

  for (int64_t i = 0; i < 500; ++i) {
    taosHashPut(hash1s, name + i * 9, 9, &i, sizeof(i));
  }

  for (int64_t i = 0; i < 5000; ++i) {
    taosHashPut(hash10s, name + i * 9, 9, &i, sizeof(i));
  }

  for (int64_t i = 0; i < 50000; ++i) {
    taosHashPut(hash100s, name + i * 9, 9, &i, sizeof(i));
  }

  for (int64_t i = 0; i < 500000; ++i) {
    taosHashPut(hash1m, name + i * 9, 9, &i, sizeof(i));
  }

  for (int64_t i = 0; i < 5000000; ++i) {
    taosHashPut(hash10m, name + i * 9, 9, &i, sizeof(i));
  }

  for (int64_t i = 0; i < 50000000; ++i) {
    taosHashPut(hash100m, name + i * 9, 9, &i, sizeof(i));
  }

  int64_t start1h = taosGetTimestampMs();
  int64_t start1hCt = taosHashGetCompTimes(hash1h);
  for (int64_t i = 0; i < 10000000; ++i) {
    ASSERT(taosHashGet(hash1h, name + (i % 50) * 9, 9));
  }
  int64_t end1h = taosGetTimestampMs();
  int64_t end1hCt = taosHashGetCompTimes(hash1h);

  int64_t start1s = taosGetTimestampMs();
  int64_t start1sCt = taosHashGetCompTimes(hash1s);
  for (int64_t i = 0; i < 10000000; ++i) {
    ASSERT(taosHashGet(hash1s, name + (i % 500) * 9, 9));
  }
  int64_t end1s = taosGetTimestampMs();
  int64_t end1sCt = taosHashGetCompTimes(hash1s);

  int64_t start10s = taosGetTimestampMs();
  int64_t start10sCt = taosHashGetCompTimes(hash10s);
  for (int64_t i = 0; i < 10000000; ++i) {
    ASSERT(taosHashGet(hash10s, name + (i % 5000) * 9, 9));
  }
  int64_t end10s = taosGetTimestampMs();
  int64_t end10sCt = taosHashGetCompTimes(hash10s);

  int64_t start100s = taosGetTimestampMs();
  int64_t start100sCt = taosHashGetCompTimes(hash100s);
  for (int64_t i = 0; i < 10000000; ++i) {
    ASSERT(taosHashGet(hash100s, name + (i % 50000) * 9, 9));
  }
  int64_t end100s = taosGetTimestampMs();
  int64_t end100sCt = taosHashGetCompTimes(hash100s);

  int64_t start1m = taosGetTimestampMs();
  int64_t start1mCt = taosHashGetCompTimes(hash1m);
  for (int64_t i = 0; i < 10000000; ++i) {
    ASSERT(taosHashGet(hash1m, name + (i % 500000) * 9, 9));
  }
  int64_t end1m = taosGetTimestampMs();
  int64_t end1mCt = taosHashGetCompTimes(hash1m);

  int64_t start10m = taosGetTimestampMs();
  int64_t start10mCt = taosHashGetCompTimes(hash10m);
  for (int64_t i = 0; i < 10000000; ++i) {
    ASSERT(taosHashGet(hash10m, name + (i % 5000000) * 9, 9));
  }
  int64_t end10m = taosGetTimestampMs();
  int64_t end10mCt = taosHashGetCompTimes(hash10m);

  int64_t start100m = taosGetTimestampMs();
  int64_t start100mCt = taosHashGetCompTimes(hash100m);
  for (int64_t i = 0; i < 10000000; ++i) {
    ASSERT(taosHashGet(hash100m, name + (i % 50000000) * 9, 9));
  }
  int64_t end100m = taosGetTimestampMs();
  int64_t end100mCt = taosHashGetCompTimes(hash100m);

H
Hongze Cheng 已提交
306
  SArray* sArray[1000] = {0};
D
dapan1121 已提交
307 308 309 310 311
  for (int64_t i = 0; i < 1000; ++i) {
    sArray[i] = taosArrayInit(100000, 9);
  }
  int64_t cap = 4;
  while (cap < 100000000) cap = (cap << 1u);
H
Hongze Cheng 已提交
312

D
dapan1121 已提交
313
  _hash_fn_t hashFp = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
H
Hongze Cheng 已提交
314
  int32_t    slotR = cap / 1000 + 1;
D
dapan1121 已提交
315
  for (int64_t i = 0; i < 10000000; ++i) {
H
Hongze Cheng 已提交
316
    char*    p = name + (i % 50000000) * 9;
D
dapan1121 已提交
317
    uint32_t v = (*hashFp)(p, 9);
H
Hongze Cheng 已提交
318
    taosArrayPush(sArray[(v % cap) / slotR], p);
D
dapan1121 已提交
319
  }
H
Hongze Cheng 已提交
320
  SArray* slArray = taosArrayInit(100000000, 9);
D
dapan1121 已提交
321 322 323 324 325 326 327 328 329 330 331 332 333
  for (int64_t i = 0; i < 1000; ++i) {
    int32_t num = taosArrayGetSize(sArray[i]);
    SArray* pArray = sArray[i];
    for (int64_t m = 0; m < num; ++m) {
      char* p = (char*)taosArrayGet(pArray, m);
      ASSERT(taosArrayPush(slArray, p));
    }
  }
  int64_t start100mS = taosGetTimestampMs();
  int64_t start100mSCt = taosHashGetCompTimes(hash100m);
  int32_t num = taosArrayGetSize(slArray);
  for (int64_t i = 0; i < num; ++i) {
    ASSERT(taosHashGet(hash100m, (char*)TARRAY_GET_ELEM(slArray, i), 9));
D
dapan1121 已提交
334 335 336
  }
  int64_t end100mS = taosGetTimestampMs();
  int64_t end100mSCt = taosHashGetCompTimes(hash100m);
D
dapan1121 已提交
337 338 339 340
  for (int64_t i = 0; i < 1000; ++i) {
    taosArrayDestroy(sArray[i]);
  }
  taosArrayDestroy(slArray);
D
dapan1121 已提交
341 342 343 344 345 346 347 348

  printf("1h \t %" PRId64 "ms,%" PRId64 "\n", end1h - start1h, end1hCt - start1hCt);
  printf("1s \t %" PRId64 "ms,%" PRId64 "\n", end1s - start1s, end1sCt - start1sCt);
  printf("10s \t %" PRId64 "ms,%" PRId64 "\n", end10s - start10s, end10sCt - start10sCt);
  printf("100s \t %" PRId64 "ms,%" PRId64 "\n", end100s - start100s, end100sCt - start100sCt);
  printf("1m \t %" PRId64 "ms,%" PRId64 "\n", end1m - start1m, end1mCt - start1mCt);
  printf("10m \t %" PRId64 "ms,%" PRId64 "\n", end10m - start10m, end10mCt - start10mCt);
  printf("100m \t %" PRId64 "ms,%" PRId64 "\n", end100m - start100m, end100mCt - start100mCt);
D
dapan1121 已提交
349
  printf("100mS \t %" PRId64 "ms,%" PRId64 "\n", end100mS - start100mS, end100mSCt - start100mSCt);
D
dapan1121 已提交
350 351 352 353 354 355 356 357 358

  taosHashCleanup(hash1h);
  taosHashCleanup(hash1s);
  taosHashCleanup(hash10s);
  taosHashCleanup(hash100s);
  taosHashCleanup(hash1m);
  taosHashCleanup(hash10m);
  taosHashCleanup(hash100m);

H
Hongze Cheng 已提交
359
  SHashObj* mhash[1000] = {0};
D
dapan1121 已提交
360
  for (int64_t i = 0; i < 1000; ++i) {
H
Hongze Cheng 已提交
361
    mhash[i] = (SHashObj*)taosHashInit(100000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
D
dapan1121 已提交
362 363 364 365 366 367
  }

  for (int64_t i = 0; i < 50000000; ++i) {
#if 0
    taosHashPut(mhash[i%1000], name + i * 9, 9, &i, sizeof(i));
#else
H
Hongze Cheng 已提交
368 369
    taosHashPut(mhash[i / 50000], name + i * 9, 9, &i, sizeof(i));
#endif
D
dapan1121 已提交
370 371 372 373 374 375 376 377 378 379 380 381 382
  }

  int64_t startMhashCt = 0;
  for (int64_t i = 0; i < 1000; ++i) {
    startMhashCt += taosHashGetCompTimes(mhash[i]);
  }

  int64_t startMhash = taosGetTimestampMs();
#if 0
  for (int32_t i = 0; i < 10000000; ++i) {
    ASSERT(taosHashGet(mhash[i%1000], name + i * 9, 9));
  }
#else
H
Hongze Cheng 已提交
383 384 385
  //  for (int64_t i = 0; i < 10000000; ++i) {
  for (int64_t i = 0; i < 50000000; i += 5) {
    ASSERT(taosHashGet(mhash[i / 50000], name + i * 9, 9));
D
dapan1121 已提交
386
  }
H
Hongze Cheng 已提交
387
#endif
D
dapan1121 已提交
388 389 390
  int64_t endMhash = taosGetTimestampMs();
  int64_t endMhashCt = 0;
  for (int64_t i = 0; i < 1000; ++i) {
H
Hongze Cheng 已提交
391
    printf(" %" PRId64, taosHashGetCompTimes(mhash[i]));
D
dapan1121 已提交
392 393 394 395 396 397 398 399 400
    endMhashCt += taosHashGetCompTimes(mhash[i]);
  }
  printf("\n100m \t %" PRId64 "ms,%" PRId64 "\n", endMhash - startMhash, endMhashCt - startMhashCt);

  for (int64_t i = 0; i < 1000; ++i) {
    taosHashCleanup(mhash[i]);
  }
}

H
Hongze Cheng 已提交
401
}  // namespace
H
hjxilinx 已提交
402 403 404 405 406 407 408

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

TEST(testCase, hashTest) {
409 410 411 412
  simpleTest();
  stringKeyTest();
  noLockPerformanceTest();
  multithreadsTest();
D
dapan1121 已提交
413
  acquireRleaseTest();
H
Hongze Cheng 已提交
414
  // perfTest();
415
}