]> rtime.felk.cvut.cz Git - can-benchmark.git/blob - latester/histogram.h
latester: Add percentiles to statistics
[can-benchmark.git] / latester / histogram.h
1 #ifndef HISTOGRAM_H
2 #define HISTOGRAM_H
3
4 struct histogram {
5         unsigned *data;
6         unsigned allocated;
7         unsigned resolution;
8 };
9
10 int histogram_init(struct histogram *h,
11                    unsigned max_value,
12                    unsigned resolution)
13 {
14         size_t mem;
15         h->allocated = max_value/resolution + 1;
16         h->resolution = resolution;
17         mem = h->allocated*sizeof(*h->data);
18         h->data = malloc(mem);
19         if (h->data) {
20                 memset(h->data, 0, mem);
21                 return 0;
22         } else
23                 return -1;
24 }
25
26 void histogram_add(struct histogram *h, int value)
27 {
28         if (value < 0) value = 0;
29         unsigned index = value / h->resolution;
30         if (index >= h->allocated)
31                 index = h->allocated - 1;
32         h->data[index]++;
33 }
34
35 void histogram_fprint(struct histogram *h, FILE *f)
36 {
37         unsigned long long sum = 0, cum;
38         unsigned i;
39
40         if (!f)
41                 return;
42
43         for (i = 0; i < h->allocated; i++)
44                 sum += h->data[i];
45         cum = sum;
46         for (i = 0; i < h->allocated; i++) {
47                 if (h->data[i] != 0) {
48                         fprintf(f, "%g %lld\n", 1e-3*(i*h->resolution), cum);
49                 }
50                 cum -= h->data[i];
51         }
52 }
53
54
55 struct histogram_stats {
56         unsigned count;
57         unsigned long long sum;
58         unsigned avg;
59         unsigned percentile[100];
60 };
61
62 void histogram_stats(struct histogram *h, struct histogram_stats *s)
63 {
64         unsigned long long sum;
65         unsigned i, j;
66
67         if (!s)
68                 return;
69
70         memset(s, 0, sizeof(*s));
71
72         for (i = 0; i < h->allocated; i++) {
73                 s->count += h->data[i];
74                 s->sum += h->data[i] * i * h->resolution;
75         }
76         if (s->count == 0)
77                 return;
78
79         s->avg = s->sum / s->count;
80
81         for (i = 0, j = 0, sum = 0; i < 100; i++) {
82                 while (sum <= i * s->count / 100)
83                         sum += h->data[j++];
84
85                 s->percentile[i] = (j-1) * h->resolution;
86         }
87         while (sum < i * s->count / 100)
88                 sum += h->data[j++];
89         s->percentile[100] = (j-1) * h->resolution;
90 }
91
92 #endif