source: tags/ms_r18q1/TOOLS/arb_perf_test.cxx

Last change on this file was 16766, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.4 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : arb_perf_test.cxx                                 //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <arbdbt.h>
12
13#include <climits>
14#include <ctime>
15#include <sys/time.h>
16
17// --------------------------------------------------------------------------------
18// data used for tests
19
20static GBDATA *gb_species_data = NULp;
21static GBDATA *gb_main         = NULp;
22
23// --------------------------------------------------------------------------------
24// Test functions
25
26static void iterate(GBDATA *gbd) {
27    for (GBDATA *gb_child = GB_child(gbd); gb_child; gb_child = GB_nextChild(gb_child)) {
28        iterate(gb_child);
29    }
30}
31
32static void test_GB_iterate_DB() { // iterate through all DB elements
33    iterate(gb_main);
34}
35static void test_GB_find_string() {
36    GB_find_string(gb_species_data, "full_name", "asdfasdf", GB_IGNORE_CASE, SEARCH_GRANDCHILD);
37}
38static void test_GB_find_string_indexed() {
39    // field 'name' is indexed by GBT_open!
40    GB_find_string(gb_species_data, "name", "asdfasdf", GB_IGNORE_CASE, SEARCH_GRANDCHILD);
41}
42
43// --------------------------------------------------------------------------------
44
45static void noop() {
46}
47
48typedef void (*test_fun)();
49
50struct Test {
51    const char  *name;
52    test_fun     fun;
53};
54
55#define TEST(fun) { #fun, test_##fun }
56
57static Test Test[] = {
58    TEST(GB_iterate_DB),
59    TEST(GB_find_string),
60    TEST(GB_find_string_indexed),
61
62    { NULp, NULp },
63};
64
65// --------------------------------------------------------------------------------
66
67static long callDelay(long loops);
68
69#define SECOND      1000000
70#define WANTED_TIME 5*SECOND // time reserved for each test
71
72static long run_test(test_fun fun, long loops, double *perCall) {
73    // returns time for test 'fun' in microseconds
74    struct timeval t1;
75    struct timeval t2;
76
77    gettimeofday(&t1, NULp);
78    for (int i = 0; i<loops; ++i) {
79        fun();
80    }
81    gettimeofday(&t2, NULp);
82
83    long usecs  = t2.tv_sec - t1.tv_sec;
84    usecs      *= SECOND;
85    usecs      += t2.tv_usec - t1.tv_usec;
86
87    static bool recurse = true;
88    if (recurse) {
89        recurse  = false;
90        usecs   -= callDelay(loops);
91        recurse  = true;
92    }
93
94    *perCall = double(usecs)/loops;
95
96    return usecs;
97}
98
99static long callDelay(long loops) {
100    static GB_HASH *call_delay_hash       = NULp;
101    if (!call_delay_hash) call_delay_hash = GBS_create_hash(100, GB_MIND_CASE);
102
103    const char *loopKey   = GBS_global_string("%li", loops);
104    long        delay = GBS_read_hash(call_delay_hash, loopKey);
105    if (!delay) {
106        double perCall;
107        delay = run_test(noop, loops, &perCall);
108        GBS_write_hash(call_delay_hash, loopKey, delay);
109    }
110    return delay;
111}
112
113static long estimate_loops(test_fun fun) {
114    long   loops    = 1;
115    double perCall;
116    long   duration = run_test(fun, loops, &perCall);
117
118    while (duration<1000) {
119        loops = (loops*10000.0)/duration+1;
120        if (loops>0) {
121            duration = run_test(fun, loops, &perCall);
122        }
123    }
124
125    loops = (loops*double(WANTED_TIME))/duration+1;
126    if (loops <= 0) loops = LONG_MAX;
127    return loops;
128}
129
130static long count_elements(GBDATA *gbd) {
131    long count = 0;
132    for (GBDATA *gb_child = GB_child(gbd); gb_child; gb_child = GB_nextChild(gb_child)) {
133        count += count_elements(gb_child);
134    }
135    return count+1; // self
136}
137
138int ARB_main(int argc, char *argv[]) {
139    GB_ERROR error = NULp;
140
141    if (argc == 0) {
142        fprintf(stderr, "arb_perf_test source.arb\n");
143        fprintf(stderr, "Test performance of some commands - see source code\n");
144
145        error = "Missing arguments";
146    }
147    else {
148        const char *in = argv[1];
149        gb_main  = GBT_open(in, "rw");
150
151        if (!gb_main) {
152            error = GB_await_error();
153        }
154        else {
155            // init test data
156            {
157                GB_transaction ta(gb_main);
158                gb_species_data = GBT_get_species_data(gb_main);
159            }
160
161            printf("Loaded DB '%s'\n", in);
162            printf(" * contains %li elements\n", count_elements(gb_main));
163            printf(" * contains %li species\n", GBT_get_species_count(gb_main));
164
165            printf("Running tests:\n");
166            for (int test = 0; Test[test].name; ++test) {
167                GB_transaction ta(gb_main);
168
169                double perCall;
170                long   esti_loops = estimate_loops(Test[test].fun);
171                long   usecs      = run_test(Test[test].fun, esti_loops, &perCall);
172
173                printf("Test #%i: %-25s %10li loops = %10li us (%10.2f us/call, %10.2f calls/sec)\n",
174                       test+1,
175                       Test[test].name,
176                       esti_loops,
177                       usecs,
178                       perCall,
179                       SECOND/perCall);
180            }
181
182            GB_close(gb_main);
183        }
184    }
185
186    if (error) {
187        fprintf(stderr, "arb_perf_test: Error: %s\n", error);
188        return EXIT_FAILURE;
189    }
190
191    return EXIT_SUCCESS;
192}
Note: See TracBrowser for help on using the repository browser.