Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added benchmark skeleton, and at least stubs for all of the necessary…
… functions
- Loading branch information
Showing
10 changed files
with
239 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
- Make h_action functions be called only after parse is complete. | ||
- Allow alternative input streams (eg, zlib, base64) | ||
- Bonus points if layered... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#include "../internal.h" | ||
|
||
int h_packrat_compile(HAllocator* mm__, HParser* parser, const void* params) { | ||
return 0; // No compilation necessary, and everything should work | ||
// out of the box. | ||
} | ||
|
||
HParseResult *h_packrat_parse(HAllocator* mm__, HParser* parser, HParseState* parse_state) { | ||
return NULL; // TODO: fill this in. | ||
} | ||
|
||
HParserBackendVTable h__packrat_backend_vtable = { | ||
.compile = h_packrat_compile, | ||
.parse = h_packrat_parse | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#include <stdio.h> | ||
#include <time.h> | ||
#include <string.h> | ||
#include "hammer.h" | ||
|
||
/* | ||
Usage: | ||
Create your parser (i.e., HParser*), and then call | ||
HBenchmarkResults* results = h_benchmark(parser, testcases); | ||
Then, you can format a report with: | ||
h_benchmark_report(stdout, results); | ||
or just generate code to make the parser run as fast as possible with: | ||
h_benchmark_dump_optimized_code(stdout, results); | ||
*/ | ||
|
||
|
||
HBenchmarkResults *h_benchmark(HParser* parser, HParserTestcase* testcases) { | ||
// For now, just output the results to stderr | ||
HParserTestcase* tc = testcases; | ||
HParserBackend backend = PB_MIN; | ||
|
||
for (backend = PB_MIN; backend < PB_MAX; backend++) { | ||
fprintf(stderr, "Compiling for backend %d ... ", backend); | ||
// Step 1: Compile grammar for given parser... | ||
if (h_compile(parser, PB_MIN, NULL) == -1) { | ||
// backend inappropriate for grammar... | ||
fprintf(stderr, "failed\n"); | ||
continue; | ||
} | ||
int tc_failed = 0; | ||
// Step 1: verify all test cases. | ||
for (tc = testcases; tc->input != NULL; tc++) { | ||
HParseResult *res = h_parse(parser, tc->input, tc->length); | ||
char* res_unamb; | ||
if (res != NULL) { | ||
res_unamb = h_write_result_unamb(res->ast); | ||
} else | ||
res_unamb = NULL; | ||
if ((res_unamb == NULL && tc->output_unambiguous == NULL) | ||
|| (strcmp(res_unamb, tc->output_unambiguous) != 0)) { | ||
// test case failed... | ||
fprintf(stderr, "failed\n"); | ||
// We want to run all testcases, for purposes of generating a | ||
// report. (eg, if users are trying to fix a grammar for a | ||
// faster backend) | ||
tc_failed++; | ||
} | ||
h_parse_result_free(res); | ||
} | ||
|
||
if (tc_failed > 0) { | ||
// Can't use this parser; skip to the next | ||
fprintf(stderr, "Backend failed testcases; skipping benchmark\n"); | ||
continue; | ||
} | ||
|
||
for (tc = testcases; tc->input != NULL; tc++) { | ||
// The goal is to run each testcase for at least 50ms each | ||
// TODO: replace this with a posix timer-based benchmark. (cf. timerfd_create, timer_create, setitimer) | ||
int count = 1, cur; | ||
struct timespec ts_start, ts_end; | ||
long long time_diff; | ||
do { | ||
count *= 2; // Yes, this means that the first run will run the function twice. This is fine, as we want multiple runs anyway. | ||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts_start); | ||
for (cur = 0; cur < count; cur++) { | ||
h_parse_result_free(h_parse(parser, tc->input, tc->length)); | ||
} | ||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts_end); | ||
|
||
// time_diff is in ns | ||
time_diff = (ts_end.tv_sec - ts_start.tv_sec) * 1000000000 + (ts_end.tv_nsec - ts_start.tv_nsec); | ||
} while (time_diff < 100000000); | ||
fprintf(stderr, "Case %d: %lld ns/parse\n", (int)(tc - testcases), time_diff / count); | ||
} | ||
} | ||
return NULL; | ||
} | ||
|
||
void h_benchmark_report(FILE* stream, HBenchmarkResults* result) { | ||
// TODO: fill in this function | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// This file contains functions related to managing multiple parse backends | ||
#include "hammer.h" | ||
#include "internal.h" | ||
|
||
static HParserBackendVTable *backends[PB_MAX] = { | ||
&h__packrat_backend_vtable, | ||
}; | ||
|
||
int h_compile(HParser* parser, HParserBackend backend, const void* params) { | ||
return h_compile__m(&system_allocator, parser, backend, params); | ||
} | ||
|
||
int h_compile__m(HAllocator* mm__, HParser* parser, HParserBackend backend, const void* params) { | ||
return backends[backend]->compile(mm__, parser, params); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// At this point, this is just a compile/link test. | ||
#include "hammer.h" | ||
|
||
HParserTestcase testcases[] = { | ||
{NULL, 0, NULL} | ||
}; | ||
|
||
void test_benchmark_1() { | ||
HParser *parser = NULL; // TODO: fill this in. | ||
|
||
HBenchmarkResults *res = h_benchmark(parser, testcases); | ||
h_benchmark_report(stderr, res); | ||
|
||
} |