diff options
author | Elliott Hughes <enh@google.com> | 2017-12-19 08:55:40 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2017-12-19 08:55:40 -0800 |
commit | 7063a838be5eb1f28f40a554944a31bab49c3211 (patch) | |
tree | 6f498b51428018eac4a519f7624b9e8131433433 /benchmarks/stdio_benchmark.cpp | |
parent | 721a5305e24b69b68ecc9431526f32131abc8f6c (diff) |
More benchmarks.
Add a hand-rolled maps line parser as something to compare our realistic
sscanf benchmark against. Also add benchmarks for the ato*/strto* family.
This patch doesn't fix the tests, which seem to have been broken by
the recent google-benchmark upgrade despite the benchmarks themselves
all working just fine. To me that's a final strike against these tests
which are hard to maintain and not obviously useful, but we can worry
about what to do with them -- whether to just delete them or to try to
turn them into tests that actually have some value -- in a separate CL.
Bug: N/A
Test: ran benchmarks
Change-Id: I6c9a77ece98d624baeb049b360876ef5c35ea7f2
Diffstat (limited to 'benchmarks/stdio_benchmark.cpp')
-rw-r--r-- | benchmarks/stdio_benchmark.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp index 872725d34..965a3ae9f 100644 --- a/benchmarks/stdio_benchmark.cpp +++ b/benchmarks/stdio_benchmark.cpp @@ -223,6 +223,7 @@ static void BM_stdio_scanf_d(benchmark::State& state) { } BIONIC_BENCHMARK(BM_stdio_scanf_d); +// Parsing maps is a common use of sscanf with a relatively complex format string. static void BM_stdio_scanf_maps(benchmark::State& state) { while (state.KeepRunning()) { uintptr_t start; @@ -236,3 +237,71 @@ static void BM_stdio_scanf_maps(benchmark::State& state) { } } BIONIC_BENCHMARK(BM_stdio_scanf_maps); + +// Hard-coded equivalent of the maps sscanf from libunwindstack/Maps.cpp for a baseline. +static int ParseMap(const char* line, const char* /*fmt*/, uintptr_t* start, uintptr_t* end, + char* permissions, uintptr_t* offset, int* name_pos) __attribute__((noinline)) { + char* str; + const char* old_str = line; + + // "%" PRIxPTR "-" + *start = strtoul(old_str, &str, 16); + if (old_str == str || *str++ != '-') return 0; + + // "%" PRIxPTR " " + old_str = str; + *end = strtoul(old_str, &str, 16); + if (old_str == str || !std::isspace(*str++)) return 0; + while (std::isspace(*str)) str++; + + // "%4s " + if (*str == '\0') return 0; + permissions[0] = *str; + str++; + permissions[1] = *str; + str++; + permissions[2] = *str; + str++; + permissions[3] = *str; + str++; + permissions[4] = 0; + if (!std::isspace(*str++)) return 0; + + // "%" PRIxPTR " " + old_str = str; + *offset = strtoul(old_str, &str, 16); + if (old_str == str || !std::isspace(*str)) return 0; + + // "%*x:%*x " + old_str = str; + (void)strtoul(old_str, &str, 16); + if (old_str == str || *str++ != ':') return 0; + if (std::isspace(*str)) return 0; + old_str = str; + (void)strtoul(str, &str, 16); + if (old_str == str || !std::isspace(*str++)) return 0; + + // "%*d " + old_str = str; + (void)strtoul(old_str, &str, 10); + if (old_str == str || (!std::isspace(*str) && *str != '\0')) return 0; + while (std::isspace(*str)) str++; + + // "%n" + *name_pos = (str - line); + return 4; +} + +static void BM_stdio_scanf_maps_baseline(benchmark::State& state) { + while (state.KeepRunning()) { + uintptr_t start; + uintptr_t end; + uintptr_t offset; + char permissions[5]; + int name_pos; + if (ParseMap("6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so", + "%" PRIxPTR "-%" PRIxPTR " %4s %" PRIxPTR " %*x:%*x %*d %n", + &start, &end, permissions, &offset, &name_pos) != 4) abort(); + } +} +BIONIC_BENCHMARK(BM_stdio_scanf_maps_baseline); |