source: tags/ms_r16q3/TOOLS/arb_perf_test.cxx

Last change on this file was 9899, checked in by epruesse, 11 years ago

pass down argc/argv to AW_root::AW_root (for GTK)
GTK will pick its parameters (e.g. —g-fatal-warnings) from argv and
remove them, hence argv must not be const and AW_root() should
be called before command line parsing (if possible).

  • 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 = 0;
21static GBDATA *gb_main         = 0;
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    { NULL, NULL },
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, 0);
78    for (int i = 0; i<loops; ++i) {
79        fun();
80    }
81    gettimeofday(&t2, 0);
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        = 0;
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{
140    GB_ERROR error = 0;
141
142    if (argc == 0) {
143        fprintf(stderr, "arb_perf_test source.arb\n");
144        fprintf(stderr, "Test performance of some commands - see source code\n");
145
146        error = "Missing arguments";
147    }
148    else {
149        const char *in = argv[1];
150        gb_main  = GBT_open(in, "rw");
151
152        if (!gb_main) {
153            error = GB_await_error();
154        }
155        else {
156            // init test data
157            {
158                GB_transaction ta(gb_main);
159                gb_species_data = GBT_get_species_data(gb_main);
160            }
161
162            printf("Loaded DB '%s'\n", in);
163            printf(" * contains %li elements\n", count_elements(gb_main));
164            printf(" * contains %li species\n", GBT_get_species_count(gb_main));
165
166            printf("Running tests:\n");
167            for (int test = 0; Test[test].name; ++test) {
168                GB_transaction ta(gb_main);
169
170                double perCall;
171                long   esti_loops = estimate_loops(Test[test].fun);
172                long   usecs      = run_test(Test[test].fun, esti_loops, &perCall);
173
174                printf("Test #%i: %-25s %10li loops = %10li us (%10.2f us/call, %10.2f calls/sec)\n",
175                       test+1,
176                       Test[test].name,
177                       esti_loops,
178                       usecs,
179                       perCall,
180                       SECOND/perCall);
181            }
182
183            GB_close(gb_main);
184        }
185    }
186
187    if (error) {
188        fprintf(stderr, "arb_perf_test: Error: %s\n", error);
189        return EXIT_FAILURE;
190    }
191
192    return EXIT_SUCCESS;
193}
Note: See TracBrowser for help on using the repository browser.