Skip to content

Commit d9fdeef

Browse files
authored
Add: benchmark (#44)
* Fixed: codecov benchmark * Added: benchmark * Added: benchmark * Fixed: lint * Added: benchmark file * Update: README.md * Fixed: comments
1 parent 3016683 commit d9fdeef

File tree

6 files changed

+240
-2
lines changed

6 files changed

+240
-2
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ file(GLOB_RECURSE
330330

331331
add_executable(jucc_benchmark ${JUCC_BENCHMARK_SOURCES})
332332

333+
add_test(NAME jucc_benchmark COMMAND jucc_benchmark)
334+
333335
target_link_libraries(jucc_benchmark PUBLIC jucc_objlib benchmark --coverage)
334336

335337
#######################################################################################################################

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ $ ninja
4343
$ ./bin/jucc_test
4444
```
4545

46+
To run the benchmarks,
47+
Note: `-DCMAKE_BUILD_TYPE=Release` is needed
48+
49+
```
50+
$ mkdir build
51+
$ cd build
52+
$ cmake -GNinja -DCMAKE_BUILD_TYPE=Release ..
53+
$ ninja
54+
$ ./bin/jucc_benchmark
55+
```
56+
4657
Before pushing or making a pull request ( The tests must pass, compulsory !! )
4758

4859
```
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
## This is the grammar file for JuCC
2+
## Edit this file to make changes to the parsing grammar
3+
## Epsilon is represented by special string EPSILON
4+
5+
## Terminals
6+
%terminals
7+
else float if int void
8+
( ) { } * + - / % ,
9+
<< >> < > <= >= = == != ;
10+
identifier integer_constant float_constant
11+
main cin cout
12+
%
13+
14+
## Non Terminals
15+
%non_terminals
16+
<primary_expression> <constant> <unary_operator> <type_specifier>
17+
<unary_expression> <multiplicative_expression> <additive_expression>
18+
<shift_expression> <relational_expression>
19+
<equality_expression> <assignment_expression> <expression>
20+
<declaration> <init_declarator_list> <init_declarator>
21+
<initializer> <declarator> <direct_declarator>
22+
<statement> <compound_statement> <block_item_list> <block_item>
23+
<expression_statement> <selection_statement> <program>
24+
%
25+
26+
## Start Symbol
27+
%start
28+
<program>
29+
%
30+
31+
## Grammar for the language
32+
%rules
33+
## Expressions
34+
<primary_expression> : identifier
35+
<primary_expression> : <constant>
36+
<primary_expression> : ( <expression> )
37+
<constant> : integer_constant
38+
<constant> : float_constant
39+
<unary_operator> : +
40+
<unary_operator> : -
41+
<unary_expression> : <primary_expression>
42+
<unary_expression> : <unary_operator> <primary_expression>
43+
<multiplicative_expression> : <unary_expression>
44+
<multiplicative_expression> : <multiplicative_expression> * <unary_expression>
45+
<multiplicative_expression> : <multiplicative_expression> / <unary_expression>
46+
<multiplicative_expression> : <multiplicative_expression> % <unary_expression>
47+
<additive_expression> : <multiplicative_expression>
48+
<additive_expression> : <additive_expression> + <multiplicative_expression>
49+
<additive_expression> : <additive_expression> - <multiplicative_expression>
50+
<shift_expression> : <additive_expression>
51+
<shift_expression> : cin >> <additive_expression>
52+
<shift_expression> : cout << <additive_expression>
53+
<shift_expression> : <shift_expression> << <additive_expression>
54+
<shift_expression> : <shift_expression> >> <additive_expression>
55+
<relational_expression> : <shift_expression>
56+
<relational_expression> : <relational_expression> < <shift_expression>
57+
<relational_expression> : <relational_expression> > <shift_expression>
58+
<relational_expression> : <relational_expression> <= <shift_expression>
59+
<relational_expression> : <relational_expression> >= <shift_expression>
60+
<equality_expression> : <relational_expression>
61+
<equality_expression> : <equality_expression> == <relational_expression>
62+
<equality_expression> : <equality_expression> != <relational_expression>
63+
<assignment_expression> : <equality_expression>
64+
<expression> : <assignment_expression>
65+
66+
## Declarations
67+
<declaration> : <type_specifier> <init_declarator_list> ;
68+
<init_declarator_list> : <init_declarator>
69+
<init_declarator_list> : <init_declarator> , <init_declarator_list>
70+
<init_declarator_list> : EPSILON
71+
<init_declarator> : <declarator>
72+
<init_declarator> : <declarator> = <initializer>
73+
<type_specifier> : void
74+
<type_specifier> : int
75+
<type_specifier> : float
76+
<declarator> : <direct_declarator>
77+
<direct_declarator> : identifier
78+
<direct_declarator> : ( <declarator> )
79+
<initializer> : <assignment_expression>
80+
81+
## Statements
82+
<statement> : <compound_statement>
83+
<statement> : <expression_statement>
84+
<statement> : <selection_statement>
85+
<compound_statement> : { <block_item_list> }
86+
<block_item_list> : <block_item>
87+
<block_item_list> : <block_item> <block_item_list>
88+
<block_item_list> : EPSILON
89+
<block_item> : <declaration>
90+
<block_item> : <statement>
91+
<expression_statement> : <expression> ;
92+
<expression_statement> : ;
93+
<selection_statement> : if ( <expression> ) <compound_statement>
94+
<selection_statement> : if ( <expression> ) <compound_statement> else <compound_statement>
95+
96+
## Main
97+
<program> : <type_specifier> main ( ) <compound_statement>
98+
%

benchmark/input/in1.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// input file for benchmarking
2+
3+
int main() {
4+
int x, y;
5+
cin >> x >> y;
6+
if (x != 0) {
7+
if (y > 0) {
8+
cout << y;
9+
} else {
10+
cout << -y;
11+
}
12+
}
13+
float z = 1 + 2 + 3 + 1000/ 50 * 23.2 * (x * y * 10);
14+
cout << x << y << z;
15+
16+
// other stuff for benchmarking
17+
float z0 = 1 + 2 + 3 + 1000/ 50 * 23.2 * (x * y * 10);
18+
float z1 = 1 + 2 - 3 + 1000/ 50 * 23.2 * (x * y * 10);
19+
float z2 = 1 + 2 / 3 + 1000/ 50 * 23.2 * (x * y * 10);
20+
float z3 = 1 + 2 * 3 + 1000/ 50 * 23.2 * (x * y * 10);
21+
float z4 = 1 + 2 % 3 + 1000/ 50 * 23.2 * (x * y * 10);
22+
float z5 = 1 + 2 > 3 + 1000/ 50 * 23.2 * (x * y * 10);
23+
float z6 = 1 + 2 == 3 + 1000/ 50 * 23.2 * (x * y * 10);
24+
float z7 = 1 + 2 != 3 + 1000/ 50 * 23.2 * (x * y * 10);
25+
float z8 = 1 + 2 >= 3 + 1000/ 50 * 23.2 * (x * y * 10);
26+
float z9 = 1 + 2 <= 3 + 1000/ 50 * 23.2 * (x * y * 10);
27+
cout << z0 << z1 << z2 << z3 << z4;
28+
cout << z5 << z6 << z7 << z8 << z9;
29+
}

benchmark/main/jucc_benchmark.cpp

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,104 @@
33

44
// NOLINTNEXTLINE
55
static void BenchmarkRadd(benchmark::State &state) {
6-
// NOLINTNEXTLINE
7-
for (auto _ : state) {
6+
for (const auto &_ : state) {
87
jucc::Radd(0, 1000000);
98
}
109
}
1110

1211
BENCHMARK(BenchmarkRadd);
12+
13+
// NOLINTNEXTLINE
14+
static void BenchmarkJuCC(benchmark::State &state) {
15+
std::string file_grammar = "../benchmark/input/benchmark_grammar.g";
16+
std::string file_input = "../benchmark/input/in1.cc";
17+
for (const auto &_ : state) {
18+
jucc::grammar::Parser grammar_parser = jucc::grammar::Parser(file_grammar.c_str());
19+
grammar_parser.Parse();
20+
jucc::grammar::Productions raw_productions = grammar_parser.GetProductions();
21+
jucc::grammar::Productions productions = jucc::utils::RemoveAllPossibleAmbiguity(raw_productions);
22+
auto nullables = jucc::utils::CalcNullables(productions);
23+
auto firsts = jucc::utils::CalcFirsts(productions, nullables);
24+
auto follows = jucc::utils::CalcFollows(productions, firsts, nullables, grammar_parser.GetStartSymbol());
25+
auto terminals = grammar_parser.GetTerminals();
26+
auto non_terminals = jucc::utils::GetAllNonTerminals(productions);
27+
jucc::parser::ParsingTable parsing_table = jucc::parser::ParsingTable(terminals, non_terminals);
28+
parsing_table.SetFirsts(firsts);
29+
parsing_table.SetFollows(follows);
30+
parsing_table.SetProductions(productions);
31+
parsing_table.BuildTable();
32+
33+
std::ifstream ifs(file_input);
34+
std::vector<std::string> input_tokens;
35+
jucc::lexer::Lexer lexer = jucc::lexer::Lexer();
36+
int token;
37+
while ((token = lexer.GetToken(ifs)) != jucc::lexer::TOK_EOF) {
38+
std::string ret_string = jucc::lexer::Lexer::GetTokenType(token);
39+
if (ret_string == "ignore") {
40+
continue;
41+
}
42+
input_tokens.emplace_back(ret_string);
43+
}
44+
45+
jucc::parser::Parser parser = jucc::parser::Parser();
46+
parser.SetInputString(input_tokens);
47+
parser.SetStartSymbol(grammar_parser.GetStartSymbol());
48+
parser.SetParsingTable(parsing_table);
49+
while (!parser.IsComplete()) {
50+
parser.ParseNextStep();
51+
}
52+
parser.BuildParseTree();
53+
}
54+
}
55+
56+
BENCHMARK(BenchmarkJuCC);
57+
58+
/*
59+
* Same as BenchmarkJuCC but without disk operations
60+
*/
61+
// NOLINTNEXTLINE
62+
static void BenchmarkJuCCCompute(benchmark::State &state) {
63+
std::string file_grammar = "../benchmark/input/benchmark_grammar.g";
64+
std::string file_input = "../benchmark/input/in1.cc";
65+
66+
jucc::grammar::Parser grammar_parser = jucc::grammar::Parser(file_grammar.c_str());
67+
grammar_parser.Parse();
68+
69+
std::ifstream ifs(file_input);
70+
std::vector<std::string> input_tokens;
71+
jucc::lexer::Lexer lexer = jucc::lexer::Lexer();
72+
int token;
73+
while ((token = lexer.GetToken(ifs)) != jucc::lexer::TOK_EOF) {
74+
std::string ret_string = jucc::lexer::Lexer::GetTokenType(token);
75+
if (ret_string == "ignore") {
76+
continue;
77+
}
78+
input_tokens.emplace_back(ret_string);
79+
}
80+
81+
for (const auto &_ : state) {
82+
jucc::grammar::Productions raw_productions = grammar_parser.GetProductions();
83+
jucc::grammar::Productions productions = jucc::utils::RemoveAllPossibleAmbiguity(raw_productions);
84+
auto nullables = jucc::utils::CalcNullables(productions);
85+
auto firsts = jucc::utils::CalcFirsts(productions, nullables);
86+
auto follows = jucc::utils::CalcFollows(productions, firsts, nullables, grammar_parser.GetStartSymbol());
87+
auto terminals = grammar_parser.GetTerminals();
88+
auto non_terminals = jucc::utils::GetAllNonTerminals(productions);
89+
jucc::parser::ParsingTable parsing_table = jucc::parser::ParsingTable(terminals, non_terminals);
90+
parsing_table.SetFirsts(firsts);
91+
parsing_table.SetFollows(follows);
92+
parsing_table.SetProductions(productions);
93+
parsing_table.BuildTable();
94+
95+
jucc::parser::Parser parser = jucc::parser::Parser();
96+
parser.SetInputString(input_tokens);
97+
parser.SetStartSymbol(grammar_parser.GetStartSymbol());
98+
parser.SetParsingTable(parsing_table);
99+
while (!parser.IsComplete()) {
100+
parser.ParseNextStep();
101+
}
102+
parser.BuildParseTree();
103+
}
104+
}
105+
106+
BENCHMARK(BenchmarkJuCCCompute);

codecov.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ comment:
2626
layout: "reach, diff, flags, files, footer"
2727
behavior: default
2828
require_changes: no
29+
30+
ignore:
31+
# ignore the third_party directory
32+
- "third_party"

0 commit comments

Comments
 (0)