Skip to content

Commit 360a535

Browse files
committed
Added preliminary test to all parser benchmarks to verify the correctness of variables used in expressions.
1 parent 844ca96 commit 360a535

16 files changed

+460
-22
lines changed

include/Benchmark.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef BENCHMARK_H
22
#define BENCHMARK_H
33

4+
#include <algorithm>
45
#include <map>
56
#include <vector>
67
#include <string>
@@ -82,4 +83,32 @@ class Benchmark
8283
std::vector<double> rate_list;
8384
};
8485

86+
inline std::vector<std::pair<std::string,double> > test_expressions()
87+
{
88+
static const std::vector<std::pair<std::string,double> > test_expressions_
89+
{
90+
std::make_pair("a + 0.0" , 1.1),
91+
std::make_pair("b + 0.0" , 2.2),
92+
std::make_pair("c + 0.0" , 3.3),
93+
std::make_pair("x + 0.0" ,2.123456),
94+
std::make_pair("y + 0.0" ,3.123456),
95+
std::make_pair("z + 0.0" ,4.123456),
96+
std::make_pair("w + 0.0" ,5.123456)
97+
};
98+
99+
return test_expressions_;
100+
}
101+
102+
template <typename T>
103+
inline bool is_equal(const T v0, const T v1)
104+
{
105+
static const T epsilon = T(0.000001);
106+
//static const T epsilon = T(std::numeric_limits<double>::epsilon());
107+
//static const T epsilon = T(std::numeric_limits<float>::epsilon());
108+
//Is either a NaN?
109+
if (v0 != v0) return false;
110+
if (v1 != v1) return false;
111+
return (std::abs(v0 - v1) <= (std::max(T(1),std::max(std::abs(v0),std::abs(v1))) * epsilon)) ? true : false;
112+
}
113+
85114
#endif

math-parser-benchmark-project/math-parser-benchmark-project.vcxproj.filters

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@
213213
<Filter>lepton</Filter>
214214
</ClCompile>
215215
<ClCompile Include="..\src\BenchNative.cpp" />
216-
<ClCompile Include="..\muParserSSE\muParserSSE.cpp" />
217216
<ClCompile Include="..\muParserSSE\mecCallback.cpp">
218217
<Filter>muparsersse</Filter>
219218
</ClCompile>
@@ -281,6 +280,9 @@
281280
<Filter>tinyexpr</Filter>
282281
</ClCompile>
283282
<ClCompile Include="..\src\BenchTinyExpr.cpp" />
283+
<ClCompile Include="..\muParserSSE\muParserSSE.cpp">
284+
<Filter>muparsersse</Filter>
285+
</ClCompile>
284286
</ItemGroup>
285287
<ItemGroup>
286288
<ClInclude Include="..\chaiscript\chaiscript_threading.hpp">

src/BenchATMSP.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,43 @@ double BenchATMSP::DoBenchmark(const std::string& sExpr, long iCount)
9292
bc.var[5] = 4.123456;
9393
bc.var[6] = 5.123456;
9494

95+
// Perform basic tests for the variables used
96+
// in the expressions
97+
{
98+
bool test_result = true;
99+
100+
auto tests_list = test_expressions();
101+
102+
for (auto test : tests_list)
103+
{
104+
ATMSB<double> test_bc;
105+
ATMSP<double> test_p;
106+
107+
bc.var[0] = 1.1;
108+
bc.var[1] = 2.2;
109+
bc.var[2] = 3.3;
110+
bc.var[3] = 2.123456;
111+
bc.var[4] = 3.123456;
112+
bc.var[5] = 4.123456;
113+
bc.var[6] = 5.123456;
114+
115+
if (
116+
test_p.parse(test_bc, test.first, "a, b, c, x, y, z, w") ||
117+
(!is_equal(test.second, bc.run()))
118+
)
119+
{
120+
test_result = false;
121+
break;
122+
}
123+
}
124+
125+
if (!test_result)
126+
{
127+
StopTimerAndReport("Failed variable test");
128+
return m_fTime1;
129+
}
130+
}
131+
95132
//Prime the I and D caches for the expression
96133
{
97134
double d0 = 0.0;

src/BenchExprTk.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,39 @@ double BenchExprTk::DoBenchmark(const std::string& sExpr, long iCount)
4040

4141
symbol_table.add_constants();
4242

43+
// Perform basic tests for the variables used
44+
// in the expressions
45+
{
46+
bool test_result = true;
47+
48+
auto tests_list = test_expressions();
49+
50+
for (auto test : tests_list)
51+
{
52+
exprtk::expression<double> test_expression;
53+
test_expression.register_symbol_table(symbol_table);
54+
55+
exprtk::parser<double> parser;
56+
57+
if (
58+
(!parser.compile(test.first,test_expression)) ||
59+
(!is_equal(test.second,test_expression.value()))
60+
)
61+
{
62+
test_result = false;
63+
break;
64+
}
65+
}
66+
67+
if (!test_result)
68+
{
69+
StopTimer(std::numeric_limits<double>::quiet_NaN(),
70+
std::numeric_limits<double>::quiet_NaN(),
71+
1);
72+
return std::numeric_limits<double>::quiet_NaN();
73+
}
74+
}
75+
4376
expression.register_symbol_table(symbol_table);
4477

4578
{

src/BenchExprTkFloat.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,39 @@ double BenchExprTkFloat::DoBenchmark(const std::string& sExpr, long iCount)
4040

4141
symbol_table.add_constants();
4242

43+
// Perform basic tests for the variables used
44+
// in the expressions
45+
{
46+
bool test_result = true;
47+
48+
auto tests_list = test_expressions();
49+
50+
for (auto test : tests_list)
51+
{
52+
exprtk::expression<float> test_expression;
53+
test_expression.register_symbol_table(symbol_table);
54+
55+
exprtk::parser<float> parser;
56+
57+
if (
58+
(!parser.compile(test.first,test_expression)) ||
59+
(!is_equal((float)test.second,test_expression.value()))
60+
)
61+
{
62+
test_result = false;
63+
break;
64+
}
65+
}
66+
67+
if (!test_result)
68+
{
69+
StopTimer(std::numeric_limits<float>::quiet_NaN(),
70+
std::numeric_limits<float>::quiet_NaN(),
71+
1);
72+
return std::numeric_limits<float>::quiet_NaN();
73+
}
74+
}
75+
4376
expression.register_symbol_table(symbol_table);
4477

4578
{

src/BenchExprTkMPFR.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "BenchExprTkMPFR.h"
2+
23
#ifdef ENABLE_MPFR
34

45
#include <cmath>
@@ -45,6 +46,39 @@ double BenchExprTkMPFR::DoBenchmark(const std::string& sExpr, long iCount)
4546

4647
symbol_table.add_constants();
4748

49+
// Perform basic tests for the variables used
50+
// in the expressions
51+
{
52+
bool test_result = true;
53+
54+
auto tests_list = test_expressions();
55+
56+
for (auto test : tests_list)
57+
{
58+
exprtk::expression<mpfr::mpreal> test_expression;
59+
test_expression.register_symbol_table(symbol_table);
60+
61+
exprtk::parser<mpfr::mpreal> parser;
62+
63+
if (
64+
(!parser.compile(test.first,test_expression)) ||
65+
(!is_equal(test.second,test_expression.value().toDouble()))
66+
)
67+
{
68+
test_result = false;
69+
break;
70+
}
71+
}
72+
73+
if (!test_result)
74+
{
75+
StopTimer(std::numeric_limits<double>::quiet_NaN(),
76+
std::numeric_limits<double>::quiet_NaN(),
77+
1);
78+
return std::numeric_limits<double>::quiet_NaN();
79+
}
80+
}
81+
4882
expression.register_symbol_table(symbol_table);
4983

5084
{

src/BenchFParser.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ double BenchFParser::DoBenchmark(const std::string& sExpr, long iCount)
2020

2121
FunctionParser Parser;
2222
Parser.AddConstant("pi", (double)M_PI);
23-
Parser.AddConstant("e", (double)M_E);
23+
Parser.AddConstant("e", (double)M_E );
2424

2525
if (Parser.Parse(sExpr.c_str(), "a,b,c,x,y,z,w") >= 0)
2626
{
@@ -39,6 +39,34 @@ double BenchFParser::DoBenchmark(const std::string& sExpr, long iCount)
3939
5.123456
4040
};
4141

42+
// Perform basic tests for the variables used
43+
// in the expressions
44+
{
45+
bool test_result = true;
46+
47+
auto tests_list = test_expressions();
48+
49+
for (auto test : tests_list)
50+
{
51+
FunctionParser TestParser;
52+
53+
if (
54+
(TestParser.Parse(test.first.c_str(), "a,b,c,x,y,z,w") >= 0) ||
55+
(!is_equal(test.second,TestParser.Eval(vals)))
56+
)
57+
{
58+
test_result = false;
59+
break;
60+
}
61+
}
62+
63+
if (!test_result)
64+
{
65+
StopTimerAndReport("Failed variable test");
66+
return m_fTime1;
67+
}
68+
}
69+
4270
//Prime the I and D caches for the expression
4371
{
4472
double d0 = 0.0;

src/BenchLepton.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include <string>
44
#include <map>
55

6-
//#include <windows.h>
76
#include <cmath>
87

98
#define LEPTON_BUILDING_STATIC_LIBRARY
@@ -56,6 +55,33 @@ double BenchLepton::DoBenchmark(const std::string& sExpr, long iCount)
5655

5756
Lepton::ExpressionProgram program = Lepton::Parser::parse(sExpr).optimize().createProgram();
5857

58+
// Perform basic tests for the variables used
59+
// in the expressions
60+
{
61+
bool test_result = true;
62+
63+
auto tests_list = test_expressions();
64+
65+
try
66+
{
67+
for (auto test : tests_list)
68+
{
69+
Lepton::ExpressionProgram test_program = Lepton::Parser::parse(test.first).optimize().createProgram();
70+
71+
if (!is_equal(test.second,test_program.evaluate(var_list)))
72+
{
73+
StopTimerAndReport("Failed variable test");
74+
return m_fTime1;
75+
}
76+
}
77+
}
78+
catch (std::exception& e)
79+
{
80+
StopTimerAndReport(e.what());
81+
return std::numeric_limits<double>::quiet_NaN();
82+
}
83+
}
84+
5985
//Prime the I and D caches for the expression
6086
{
6187
double d0 = 0.0;

src/BenchMTParser.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "BenchMTParser.h"
22

33
#include <cmath>
4-
#include <Oleauto.h>
54
// MTParser
65
#include "MTParser/MTParserLib/MTParser.h"
76
#include "MTParser/MTParserLib/MTParserExcepStrEng.h"
@@ -76,6 +75,51 @@ double BenchMTParser::DoBenchmark(const std::string& sExpr, long iCount)
7675

7776
p.defineFunc(new ExpFct());
7877

78+
// Perform basic tests for the variables used
79+
// in the expressions
80+
{
81+
bool test_result = true;
82+
83+
auto tests_list = test_expressions();
84+
85+
for (auto test : tests_list)
86+
{
87+
MTParser test_p;
88+
test_p.defineVar("a", &a);
89+
test_p.defineVar("b", &b);
90+
test_p.defineVar("c", &c);
91+
92+
test_p.defineVar("x", &x);
93+
test_p.defineVar("y", &y);
94+
test_p.defineVar("z", &z);
95+
test_p.defineVar("w", &w);
96+
97+
test_p.defineFunc(new ExpFct());
98+
99+
try
100+
{
101+
test_p.compile(test.first.c_str());
102+
103+
if (!is_equal(test.second,test_p.evaluate()))
104+
{
105+
test_result = false;
106+
break;
107+
}
108+
}
109+
catch(MTParserException&)
110+
{
111+
test_result = false;
112+
break;
113+
}
114+
}
115+
116+
if (!test_result)
117+
{
118+
StopTimerAndReport("Failed variable test");
119+
return m_fTime1;
120+
}
121+
}
122+
79123
double fTime = 0;
80124
double fRes = 0;
81125
double fSum = 0;
@@ -84,7 +128,7 @@ double BenchMTParser::DoBenchmark(const std::string& sExpr, long iCount)
84128
{
85129
p.compile(sExpr.c_str());
86130
}
87-
catch(MTParserException &e)
131+
catch(MTParserException& e)
88132
{
89133
StopTimerAndReport(e.getDesc(0).c_str());
90134
return std::numeric_limits<double>::quiet_NaN();

0 commit comments

Comments
 (0)