Replace use of NULL by C++11 nullptr.
[ginac.git] / check / test_runner.h
1 /** @file test_runner.h
2  *
3  *  Utility functions for benchmarking. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #ifndef GINAC_CHECK_TEST_RUNNER_H
24 #define GINAC_CHECK_TEST_RUNNER_H
25
26 #include "timer.h"
27
28 #include <cstdlib>
29 #include <ctime>
30 #include <iostream>
31 #include <string>
32
33 template<typename T> static void 
34 run_benchmark(T& benchmark,
35               const unsigned ntests = 10,
36               const std::clock_t t_annoying = 15*CLOCKS_PER_SEC,
37               const std::clock_t t_min = CLOCKS_PER_SEC/100)
38 {
39         const std::clock_t start(std::clock());
40         std::clock_t elapsed(start);
41
42         timer P36;
43         unsigned n = 0;
44         double t = 0;
45         bool go_on = true;
46         do {
47                 ++n;
48                 P36.start();
49                 benchmark.run();
50                 t += P36.read();
51                 go_on = benchmark.check();
52                 if (!go_on)
53                         break;
54                 elapsed = std::clock() - start;
55                 if (elapsed > t_annoying)
56                         break;
57         } while (n <= ntests || elapsed < t_min);
58         t /= n;
59         benchmark.print_result(t);
60 }
61
62 // By default long-running timings are disabled (to not annoy the user).
63 // If the GINAC_RUN_EXPENSIVE_TIMINGS environment variable is set to "1",
64 // some of them (which are supposed to be relatively fast) will be enabled.
65 // If GINAC_RUN_EXPENSIVE_TIMINGS is set to "2", all timings are enabled.
66 static int run_expensive_timings_p()
67 {
68         static int value = 0;
69         static int cc = 0;
70         static const std::string env_name("GINAC_RUN_EXPENSIVE_TIMINGS");
71         if (cc++ == 0) {
72                 char* envvar = std::getenv(env_name.c_str());
73                 if (envvar != nullptr) {
74                         value = std::atoi(envvar);
75                         if (value < 0 || value > 2)
76                                 value = 0;
77                 }
78                 if (value) {
79                         std::cerr << "WARNING: "
80                                 << "long-running timings are ENABLED."
81                                 << std::endl
82                                 << "Unset the \"" << env_name << "\" "
83                                 << "environment variable skip them."
84                                 << std::endl;
85                 }
86         }
87         return value;
88 }
89
90 #endif // ndef GINAC_CHECK_TEST_RUNNER_H