-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
utlity: Add benchmark for string-utility functions #2348
Changes from 6 commits
2804d6c
8eb9e25
29bc713
8fe318b
5e5e8a4
b79d16a
70b105d
be822f4
fcdfe13
daf4d41
9057266
c94cf1d
dc1db43
5132ae7
bcf5812
b22ea04
dda3cda
12b97c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/bin/bash | ||
|
||
set -x | ||
|
||
export COMMIT="e1c3a83b8197cf02e794f61228461c27d4e78cfb" # benchmark @ Jan 11, 2018 | ||
|
||
git clone https://github.com/google/benchmark.git | ||
(cd benchmark; git reset --hard "$COMMIT") | ||
git clone https://github.com/google/googletest.git benchmark/googletest | ||
mkdir build | ||
|
||
cd build | ||
cmake -G "Unix Makefiles" ../benchmark -DCMAKE_BUILD_TYPE=RELEASE | ||
make | ||
cp src/libbenchmark.a "$THIRDPARTY_BUILD"/lib | ||
cd ../benchmark | ||
|
||
pwd | ||
include_dir="$THIRDPARTY_BUILD/include/testing/base/public" | ||
mkdir -p "$include_dir" | ||
cp include/benchmark/benchmark.h "$include_dir" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,6 +98,11 @@ void StringUtil::rtrim(std::string& source) { | |
} | ||
} | ||
|
||
absl::string_view StringUtil::rightTrim(absl::string_view source) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jmarantz I created a new class StringViewUtil with similar method/implementation in my last commit. Check this out: https://github.com/gsagula/envoy/blob/02ba40dd236645b89aec7689a81c9ff89f71dfc2/source/common/common/utility.cc#L222 Comment: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In absl -- and in earlier versions of similar libraries in Google & Chromium, they are co-mingled. Note that absl::string_view is I think intended as a stop-gap until C++17, when std::string_view (http://en.cppreference.com/w/cpp/string/basic_string_view) becomes available. The reason -- I think -- that they are co-mingled is that there's no reason for the ones that take std::string arguments to exist at all. E.g. in my example if you want to right-strip a std::string you can just pass in it, because absl::string_view has an implicit constructor from std::string, though it requires an explicit std::string out-conversion, e.g.:
Ordinarily, though, if the backing-store stays alive along enough, you can just live in the string_view world and never make copies. See https://github.com/abseil/abseil-cpp/blob/master/absl/strings/strip.h where the doc speaks in terms of std::string but actually all the functions take string_view. So my preference is that you replace the ones in StringUtil:: rather than adding new alternatives. This will help spread the knowledge about string_view's performance by eliminating the slower equivalent. Having said that, I knew your PR was coming, and the only reason I added my own version of rightStrip was as a testing vehicle for the benchmarking integration. And I want the benchmarking for something unrelated (faster startup in the presence of giant configs). Do you think you could split your StringUtil stuff in your PR into a smaller one, in which you also eliminate entirely the old rtrim and fix its call-sites? Unfortunately the rtrim function's signature (modifying a std::string&) can't be fixed in place. What I'll do in any case is move my new utility function into the benchmark code itself, and your version can be authoritative, and I'll have a TODO on mine to delete it it and call yours instead once it's in. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
source.remove_suffix(source.size() - source.find_last_not_of(" \t\f\v\n\r") - 1); | ||
return source; | ||
} | ||
|
||
size_t StringUtil::strlcpy(char* dst, const char* src, size_t size) { | ||
strncpy(dst, src, size - 1); | ||
dst[size - 1] = '\0'; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,8 @@ licenses(["notice"]) # Apache 2 | |
|
||
load( | ||
"//bazel:envoy_build_system.bzl", | ||
"envoy_cc_binary", | ||
"envoy_cc_library", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed. |
||
"envoy_cc_test", | ||
"envoy_package", | ||
) | ||
|
@@ -69,3 +71,20 @@ envoy_cc_test( | |
srcs = ["callback_impl_test.cc"], | ||
deps = ["//source/common/common:callback_impl_lib"], | ||
) | ||
|
||
envoy_cc_library( | ||
name = "utility_speed_test_lib", | ||
srcs = ["utility_speed_test.cc"], | ||
external_deps = [ | ||
"abseil_strings", | ||
"benchmark", | ||
], | ||
deps = [ | ||
"//source/common/common:utility_lib", | ||
], | ||
) | ||
|
||
envoy_cc_binary( | ||
name = "utility_speed_test", | ||
deps = ["utility_speed_test_lib"], | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How come the binary/lib split here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. envoy_cc_binary does not allow an external lib. I'll add that as a comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could also extend |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include <iostream> | ||
|
||
#include "common/common/utility.h" | ||
|
||
#include "testing/base/public/benchmark.h" | ||
|
||
static const char TextToTrim[] = "\t the quick brown fox jumps over the lazy dog\n\r\n"; | ||
static size_t TextToTrimLength = sizeof(TextToTrim) - 1; | ||
|
||
// NOLINT(namespace-envoy) | ||
|
||
static void printResults(int accum, int iters) { | ||
std::cout << "avg trimmed=" << static_cast<float>(accum) / iters << " of " << iters << " iters." | ||
<< std::endl; | ||
} | ||
|
||
static void BM_RTrimString(benchmark::State& state) { | ||
int accum = 0; | ||
int iters = 0; | ||
for (auto _ : state) { | ||
std::string text(TextToTrim, TextToTrimLength); | ||
Envoy::StringUtil::rtrim(text); | ||
accum += TextToTrimLength - text.size(); | ||
++iters; | ||
} | ||
printResults(accum, iters); | ||
} | ||
BENCHMARK(BM_RTrimString); | ||
|
||
static void BM_RTrimStringView(benchmark::State& state) { | ||
int accum = 0; | ||
int iters = 0; | ||
for (auto _ : state) { | ||
absl::string_view text(TextToTrim, TextToTrimLength); | ||
text = Envoy::StringUtil::rightTrim(text); | ||
accum += TextToTrimLength - text.size(); | ||
++iters; | ||
} | ||
printResults(accum, iters); | ||
} | ||
BENCHMARK(BM_RTrimStringView); | ||
|
||
int main(int argc, char** argv) { | ||
benchmark::Initialize(&argc, argv); | ||
if (benchmark::ReportUnrecognizedArguments(argc, argv)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: braces on even single line There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done; this was just a c&p from the example in benchmark.h, but I added the braces. |
||
return 1; | ||
benchmark::RunSpecifiedBenchmarks(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, the new preferred way to add external deps is https://github.com/envoyproxy/envoy/blob/master/bazel/EXTERNAL_DEPS.md#adding-external-dependencies-to-envoy-genrule-repository.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll continue to iterate on that.