1 /*
2  * TINYEXPR - Tiny recursive descent parser and evaluation engine in C
3  *
4  * Copyright (c) 2015, 2016 Lewis Van Winkle
5  *
6  * http://CodePlea.com
7  *
8  * This software is provided 'as-is', without any express or implied
9  * warranty. In no event will the authors be held liable for any damages
10  * arising from the use of this software.
11  *
12  * Permission is granted to anyone to use this software for any purpose,
13  * including commercial applications, and to alter it and redistribute it
14  * freely, subject to the following restrictions:
15  *
16  * 1. The origin of this software must not be misrepresented; you must not
17  * claim that you wrote the original software. If you use this software
18  * in a product, an acknowledgement in the product documentation would be
19  * appreciated but is not required.
20  * 2. Altered source versions must be plainly marked as such, and must not be
21  * misrepresented as being the original software.
22  * 3. This notice may not be removed or altered from any source distribution.
23  */
24 
25 #include <stdio.h>
26 #include <time.h>
27 #include <math.h>
28 #include "tinyexpr.h"
29 
30 
31 
32 #define loops 10000
33 
34 
35 
36 typedef double (*function1)(double);
37 
bench(const char * expr,function1 func)38 void bench(const char *expr, function1 func) {
39     int i, j;
40     volatile double d;
41     double tmp;
42     clock_t start;
43 
44     te_variable lk = {"a", &tmp};
45 
46     printf("Expression: %s\n", expr);
47 
48     printf("native ");
49     start = clock();
50     d = 0;
51     for (j = 0; j < loops; ++j)
52         for (i = 0; i < loops; ++i) {
53             tmp = i;
54             d += func(tmp);
55         }
56     const int nelapsed = (clock() - start) * 1000 / CLOCKS_PER_SEC;
57 
58     /*Million floats per second input.*/
59     printf(" %.5g", d);
60     if (nelapsed)
61         printf("\t%5dms\t%5dmfps\n", nelapsed, loops * loops / nelapsed / 1000);
62     else
63         printf("\tinf\n");
64 
65 
66 
67 
68     printf("interp ");
69     te_expr *n = te_compile(expr, &lk, 1, 0);
70     start = clock();
71     d = 0;
72     for (j = 0; j < loops; ++j)
73         for (i = 0; i < loops; ++i) {
74             tmp = i;
75             d += te_eval(n);
76         }
77     const int eelapsed = (clock() - start) * 1000 / CLOCKS_PER_SEC;
78     te_free(n);
79 
80     /*Million floats per second input.*/
81     printf(" %.5g", d);
82     if (eelapsed)
83         printf("\t%5dms\t%5dmfps\n", eelapsed, loops * loops / eelapsed / 1000);
84     else
85         printf("\tinf\n");
86 
87 
88     printf("%.2f%% longer\n", (((double)eelapsed / nelapsed) - 1.0) * 100.0);
89 
90 
91     printf("\n");
92 }
93 
94 
a5(double a)95 double a5(double a) {
96     return a+5;
97 }
98 
a52(double a)99 double a52(double a) {
100     return (a+5)*2;
101 }
102 
a10(double a)103 double a10(double a) {
104     return a+(5*2);
105 }
106 
as(double a)107 double as(double a) {
108     return sqrt(pow(a, 1.5) + pow(a, 2.5));
109 }
110 
al(double a)111 double al(double a) {
112     return (1/(a+1)+2/(a+2)+3/(a+3));
113 }
114 
main(int argc,char * argv[])115 int main(int argc, char *argv[])
116 {
117 
118     bench("sqrt(a^1.5+a^2.5)", as);
119     bench("a+5", a5);
120     bench("a+(5*2)", a10);
121     bench("(a+5)*2", a52);
122     bench("(1/(a+1)+2/(a+2)+3/(a+3))", al);
123 
124     return 0;
125 }
126