You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by mg...@apache.org on 2025/04/22 07:58:16 UTC
(kudu) branch branch-1.18.x updated: [webserver] reduce memory allocations and copying for responses
This is an automated email from the ASF dual-hosted git repository.
mgreber pushed a commit to branch branch-1.18.x
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/branch-1.18.x by this push:
new 1a1fbc1a9 [webserver] reduce memory allocations and copying for responses
1a1fbc1a9 is described below
commit 1a1fbc1a913eacab521558c2d2200f7b1bb2a67d
Author: Alexey Serbin <al...@apache.org>
AuthorDate: Thu Mar 6 20:42:41 2025 -0800
[webserver] reduce memory allocations and copying for responses
This patch optimizes handling the WebResponse::response field, swapping
the underlying rdbuf in ostringstream instead of materializing it
as std::string and copying over the data from one stream to another.
There are no functional modifications in this changelist.
Change-Id: I4085ab8150ecd04972d9eac8633226845b365830
Reviewed-on: http://gerrit.cloudera.org:8080/22796
Reviewed-by: Yifan Zhang <ch...@163.com>
Reviewed-by: Abhishek Chennaka <ac...@cloudera.com>
Tested-by: Alexey Serbin <al...@apache.org>
(cherry picked from commit 887a87dd9c6cfc29999e0eb9c55e559cdeefe59f)
Reviewed-on: http://gerrit.cloudera.org:8080/22798
---
src/kudu/server/webserver.cc | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/kudu/server/webserver.cc b/src/kudu/server/webserver.cc
index c8c79ff6a..61012abd1 100644
--- a/src/kudu/server/webserver.cc
+++ b/src/kudu/server/webserver.cc
@@ -40,6 +40,7 @@
#include <unordered_set>
#include <utility>
#include <vector>
+// IWYU pragma: no_include <__string>
#include <boost/algorithm/string/case_conv.hpp>
#include <gflags/gflags.h>
@@ -697,27 +698,28 @@ void Webserver::SendResponse(struct sq_connection* connection,
DCHECK(req);
stringstream ss;
RenderMainTemplate(*req, resp->output.str(), &ss);
- resp->output.str(ss.str());
+ resp->output.rdbuf()->swap(*ss.rdbuf());
}
// Check if gzip compression is accepted by the caller. If so, compress the
// content and replace the prerendered output.
- const char* accept_encoding_str = sq_get_header(connection, "Accept-Encoding");
+ auto& output = resp->output;
bool is_compressed = false;
+ const char* accept_encoding_str = sq_get_header(connection, "Accept-Encoding");
vector<string> encodings = strings::Split(accept_encoding_str, ",");
for (string& encoding : encodings) {
StripWhiteSpace(&encoding);
if (encoding == "gzip") {
// Don't bother compressing empty content.
- string uncompressed = resp->output.str();
- if (uncompressed.empty()) {
+ DCHECK(output.good());
+ if (output.tellp() == 0) {
break;
}
ostringstream oss;
- const auto s = zlib::Compress(uncompressed, &oss);
+ const auto s = zlib::Compress(output.str(), &oss);
if (PREDICT_TRUE(s.ok())) {
- resp->output.str(oss.str());
+ output.swap(oss);
is_compressed = true;
} else {
LOG(WARNING) << "Could not compress output: " << s.ToString();
@@ -728,7 +730,7 @@ void Webserver::SendResponse(struct sq_connection* connection,
// We've deferred constructing the content for as long as possible; we must
// do so now so that we can determine the content length.
- string body = resp->output.str();
+ string body = output.str();
// Buffers up the headers and content as follows:
//
@@ -850,7 +852,7 @@ void Webserver::RegisterPathHandler(const string& path, const string& alias,
if (render_path != "/home" || is_started_) {
stringstream out;
Render(render_path, resp.output, style_mode, &out);
- rendered_resp->output << out.rdbuf();
+ rendered_resp->output.rdbuf()->swap(*out.rdbuf());
}
};
RegisterPrerenderedPathHandler(path, alias, wrapped_cb, style_mode, is_on_nav_bar);