source: branches/port5/TOOLS/arb_perf_test.cxx

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