Faster, better (recursive descent) expression parser.
[ginac.git] / check / time_parser.cpp
1 #include <iostream>
2 #include <string>
3 #include <sstream>
4 #include <cstddef>
5 #include <cstdlib>
6 #include <vector>
7 #include <stdexcept>
8 #include "ginac.h"
9 #include "parser/parser.hpp"
10 #include "timer.h"
11 extern void randomify_symbol_serials();
12 using namespace std;
13 using namespace GiNaC;
14
15 /// make a string "1+x+2*x^2+...+n*x^n"
16 static string prepare_str(const unsigned n, const char x = 'x')
17 {
18         ostringstream s;
19         s << x;
20         for (unsigned i = 2; i < n; i++)
21                 s << '+' << i << '*' << x << '^' << i; 
22         return s.str();
23 }
24
25 void benchmark_and_cmp(const string& srep, double& t_new, double& t_old)
26 {
27         parser the_parser;
28         timer RSD10;
29         RSD10.start();
30         ex e = the_parser(srep);
31         t_new = RSD10.read();
32         RSD10.stop();
33         if (t_new > 2.0)
34                 cout << '.' << flush;
35
36         symtab syms = the_parser.get_syms();
37         const symbol x = find_or_insert_symbol("x", syms, true);
38         lst sl;
39         sl = x;
40         RSD10.start();
41         ex e2(srep, sl);
42         t_old = RSD10.read();
43         
44         if (t_old > 2.0)
45                 cout << '.' << flush;
46
47         ex dif = (e - e2).expand();
48         if (!dif.is_zero()) {
49                 cerr << "Got a difference: " << dif << endl;
50                 throw std::logic_error("New and old parser give different results");
51         }
52 }
53
54 int main(int argc, char** argv)
55 {
56         cout << "timing GiNaC parser..." << flush;
57         randomify_symbol_serials();
58         unsigned n_min = 1024;
59         unsigned n_max = 32768;
60         if (argc > 1)
61                 n_max = atoi(argv[1]);
62
63         vector<double> times_new, times_old;
64         vector<unsigned> ns;
65         for (unsigned n = n_min; n <= n_max; n = n << 1) {
66                 double t_new, t_old;
67                 string srep = prepare_str(n);
68                 benchmark_and_cmp(srep, t_new, t_old);
69                 times_new.push_back(t_new);
70                 times_old.push_back(t_old);
71                 ns.push_back(n);
72         }
73
74         cout << "OK" << endl;
75         cout << "# terms  new parser, s  old parser, s" << endl;
76         for (size_t i = 0; i < times_new.size(); i++)
77                 cout << " " << ns[i] << '\t' << times_new[i] << '\t' << times_old[i] << endl;
78         return 0;
79 }