Modify argument parser for multiple arguments.
Currently, if a test is created like this:
BIONIC_BENCHMARK_WITH_ARG(BM_bench, "16");
Everything works as expected, a benchmark is created of BM_bench/16.
However, it is not possible to specify a benchmark should be called with
one argument, but iterate over different values. The example:
BIONIC_BENCHMARK_WITH_ARG(BM_bench, "16 32");
Creates a single benchmark run with two arguments:
BM_bench/16/32
This change modifies the algorithm to make it possible to create multiple
instances of the benchmark iterating over each argument as a single
argument. After this change, two benchmarks are executed:
BM_bench/16
BM_bench/32
To do the previous behavior, use:
BIONIC_BENCHMARK_WITH_ARG(BM_bench, "16/32");
This will create a single benchmark with two args. This format does
not support spaces in the args, so "16 / 32" is not valid.
Modified the test_small.xml to use the new format.
Test: All unit tests pass.
Change-Id: I6f486e1d4a90580c3dace0581ea65f439911ef5a
diff --git a/benchmarks/bionic_benchmarks.cpp b/benchmarks/bionic_benchmarks.cpp
index 187ee76..74966c0 100644
--- a/benchmarks/bionic_benchmarks.cpp
+++ b/benchmarks/bionic_benchmarks.cpp
@@ -336,16 +336,36 @@
return to_populate;
}
- to_populate->push_back(std::vector<int64_t>());
- std::stringstream sstream(args);
- std::string argstr;
- while (sstream >> argstr) {
- char* check_null;
- int converted = static_cast<int>(strtol(argstr.c_str(), &check_null, 10));
- if (*check_null) {
- errx(1, "ERROR: Args str %s contains an invalid macro or int.", args.c_str());
+ std::string trimmed_args = android::base::Trim(args);
+ if (!trimmed_args.empty()) {
+ std::stringstream sstream(trimmed_args);
+ std::string argstr;
+ while (sstream >> argstr) {
+ char* check_null;
+ int converted = static_cast<int>(strtol(argstr.c_str(), &check_null, 10));
+ if (*check_null == '\0') {
+ to_populate->emplace_back(std::vector<int64_t>{converted});
+ continue;
+ } else if (*check_null == '/') {
+ // The only supported format with a / is \d+(/\d+)\s*. Example 8/8/8 or 16/23.
+ std::vector<int64_t> test_args{converted};
+ while (true) {
+ converted = static_cast<int>(strtol(check_null + 1, &check_null, 10));
+ test_args.push_back(converted);
+ if (*check_null == '\0') {
+ to_populate->emplace_back(std::move(test_args));
+ break;
+ } else if (*check_null != '/') {
+ errx(1, "ERROR: Args str %s contains an invalid macro or int.", args.c_str());
+ }
+ }
+ } else {
+ errx(1, "ERROR: Args str %s contains an invalid macro or int.", args.c_str());
+ }
}
- (*to_populate)[0].push_back(converted);
+ } else {
+ // No arguments, only the base benchmark.
+ to_populate->emplace_back(std::vector<int64_t>{});
}
return to_populate;
}
diff --git a/benchmarks/test_suites/test_from_each.xml b/benchmarks/test_suites/test_from_each.xml
index bad18e7..51c14b6 100644
--- a/benchmarks/test_suites/test_from_each.xml
+++ b/benchmarks/test_suites/test_from_each.xml
@@ -20,7 +20,7 @@
</fn>
<fn>
<name>BM_string_memcpy</name>
- <args>512 4 4</args>
+ <args>512/4/4</args>
</fn>
<fn>
<name>BM_time_clock_gettime</name>
diff --git a/benchmarks/test_suites/test_medium.xml b/benchmarks/test_suites/test_medium.xml
index 9528af3..0d29a99 100644
--- a/benchmarks/test_suites/test_medium.xml
+++ b/benchmarks/test_suites/test_medium.xml
@@ -8,7 +8,7 @@
<fn>
<name>BM_string_memcpy</name>
<iterations>25</iterations>
- <args>512 4 4</args>
+ <args>512/4/4</args>
</fn>
<fn>
<name>BM_property_get</name>
diff --git a/benchmarks/test_suites/test_small.xml b/benchmarks/test_suites/test_small.xml
index a4cc285..66d3732 100644
--- a/benchmarks/test_suites/test_small.xml
+++ b/benchmarks/test_suites/test_small.xml
@@ -1,11 +1,11 @@
<fn>
<name>BM_string_memcmp</name>
- <args>8 8 8</args>
+ <args>8/8/8</args>
</fn>
<fn>
<name>BM_math_sqrt</name>
</fn>
<fn>
<name>BM_property_get</name>
- <args>1</args>
+ <args>1 2 3</args>
</fn>
diff --git a/benchmarks/tests/interface_test.cpp b/benchmarks/tests/interface_test.cpp
index e7b96d5..1d620d1 100644
--- a/benchmarks/tests/interface_test.cpp
+++ b/benchmarks/tests/interface_test.cpp
@@ -192,9 +192,11 @@
TEST_F(SystemTests, small) {
std::string expected =
- "BM_string_memcmp/8/8/8/iterations:1\n"
- "BM_math_sqrt/iterations:1\n"
- "BM_property_get/1/iterations:1\n";
+ "BM_string_memcmp/8/8/8/iterations:1\n"
+ "BM_math_sqrt/iterations:1\n"
+ "BM_property_get/1/iterations:1\n"
+ "BM_property_get/2/iterations:1\n"
+ "BM_property_get/3/iterations:1\n";
Verify(expected, 0, std::vector<const char*>{GetBionicXmlArg("test_small.xml").c_str(),
"--bionic_iterations=1"});
}
@@ -238,17 +240,18 @@
std::string expected =
"BM_string_memcpy/8/8/8/iterations:1\n"
"BM_math_log10/iterations:1\n";
- Verify(expected, 0, std::vector<const char*>{"--bionic_extra=BM_string_memcpy 8 8 8",
- "--bionic_extra=BM_math_log10",
- "--bionic_iterations=1"});
+ Verify(expected, 0,
+ std::vector<const char*>{"--bionic_extra=BM_string_memcpy 8/8/8",
+ "--bionic_extra=BM_math_log10", "--bionic_iterations=1"});
}
TEST_F(SystemTests, cmd_args_no_iter) {
std::string expected =
"BM_string_memcpy/8/8/8\n"
"BM_math_log10\n";
- Verify(expected, 0, std::vector<const char*>{"--bionic_extra=BM_string_memcpy 8 8 8",
- "--bionic_extra=BM_math_log10"});
+ Verify(expected, 0,
+ std::vector<const char*>{"--bionic_extra=BM_string_memcpy 8/8/8",
+ "--bionic_extra=BM_math_log10"});
}
TEST_F(SystemTests, xml_and_args) {