Mercurial
comparison third_party/wrk/src/stats.c @ 178:94705b5986b3
[ThirdParty] Added WRK and luajit for load testing.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Thu, 22 Jan 2026 20:10:30 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 177:24fe8ff94056 | 178:94705b5986b3 |
|---|---|
| 1 // Copyright (C) 2012 - Will Glozer. All rights reserved. | |
| 2 | |
| 3 #include <inttypes.h> | |
| 4 #include <stdlib.h> | |
| 5 #include <math.h> | |
| 6 | |
| 7 #include "stats.h" | |
| 8 #include "zmalloc.h" | |
| 9 | |
| 10 stats *stats_alloc(uint64_t max) { | |
| 11 uint64_t limit = max + 1; | |
| 12 stats *s = zcalloc(sizeof(stats) + sizeof(uint64_t) * limit); | |
| 13 s->limit = limit; | |
| 14 s->min = UINT64_MAX; | |
| 15 return s; | |
| 16 } | |
| 17 | |
| 18 void stats_free(stats *stats) { | |
| 19 zfree(stats); | |
| 20 } | |
| 21 | |
| 22 int stats_record(stats *stats, uint64_t n) { | |
| 23 if (n >= stats->limit) return 0; | |
| 24 __sync_fetch_and_add(&stats->data[n], 1); | |
| 25 __sync_fetch_and_add(&stats->count, 1); | |
| 26 uint64_t min = stats->min; | |
| 27 uint64_t max = stats->max; | |
| 28 while (n < min) min = __sync_val_compare_and_swap(&stats->min, min, n); | |
| 29 while (n > max) max = __sync_val_compare_and_swap(&stats->max, max, n); | |
| 30 return 1; | |
| 31 } | |
| 32 | |
| 33 void stats_correct(stats *stats, int64_t expected) { | |
| 34 for (uint64_t n = expected * 2; n <= stats->max; n++) { | |
| 35 uint64_t count = stats->data[n]; | |
| 36 int64_t m = (int64_t) n - expected; | |
| 37 while (count && m > expected) { | |
| 38 stats->data[m] += count; | |
| 39 stats->count += count; | |
| 40 m -= expected; | |
| 41 } | |
| 42 } | |
| 43 } | |
| 44 | |
| 45 long double stats_mean(stats *stats) { | |
| 46 if (stats->count == 0) return 0.0; | |
| 47 | |
| 48 uint64_t sum = 0; | |
| 49 for (uint64_t i = stats->min; i <= stats->max; i++) { | |
| 50 sum += stats->data[i] * i; | |
| 51 } | |
| 52 return sum / (long double) stats->count; | |
| 53 } | |
| 54 | |
| 55 long double stats_stdev(stats *stats, long double mean) { | |
| 56 long double sum = 0.0; | |
| 57 if (stats->count < 2) return 0.0; | |
| 58 for (uint64_t i = stats->min; i <= stats->max; i++) { | |
| 59 if (stats->data[i]) { | |
| 60 sum += powl(i - mean, 2) * stats->data[i]; | |
| 61 } | |
| 62 } | |
| 63 return sqrtl(sum / (stats->count - 1)); | |
| 64 } | |
| 65 | |
| 66 long double stats_within_stdev(stats *stats, long double mean, long double stdev, uint64_t n) { | |
| 67 long double upper = mean + (stdev * n); | |
| 68 long double lower = mean - (stdev * n); | |
| 69 uint64_t sum = 0; | |
| 70 | |
| 71 for (uint64_t i = stats->min; i <= stats->max; i++) { | |
| 72 if (i >= lower && i <= upper) { | |
| 73 sum += stats->data[i]; | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 return (sum / (long double) stats->count) * 100; | |
| 78 } | |
| 79 | |
| 80 uint64_t stats_percentile(stats *stats, long double p) { | |
| 81 uint64_t rank = round((p / 100.0) * stats->count + 0.5); | |
| 82 uint64_t total = 0; | |
| 83 for (uint64_t i = stats->min; i <= stats->max; i++) { | |
| 84 total += stats->data[i]; | |
| 85 if (total >= rank) return i; | |
| 86 } | |
| 87 return 0; | |
| 88 } | |
| 89 | |
| 90 uint64_t stats_popcount(stats *stats) { | |
| 91 uint64_t count = 0; | |
| 92 for (uint64_t i = stats->min; i <= stats->max; i++) { | |
| 93 if (stats->data[i]) count++; | |
| 94 } | |
| 95 return count; | |
| 96 } | |
| 97 | |
| 98 uint64_t stats_value_at(stats *stats, uint64_t index, uint64_t *count) { | |
| 99 *count = 0; | |
| 100 for (uint64_t i = stats->min; i <= stats->max; i++) { | |
| 101 if (stats->data[i] && (*count)++ == index) { | |
| 102 *count = stats->data[i]; | |
| 103 return i; | |
| 104 } | |
| 105 } | |
| 106 return 0; | |
| 107 } |