Skip to content

Commit d7dba9d

Browse files
committed
add benchmarks for Response
1 parent fb6d548 commit d7dba9d

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

src/workerd/tests/BUILD.bazel

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ wd_cc_benchmark(
9696
deps = [":test-fixture"],
9797
)
9898

99+
wd_cc_benchmark(
100+
name = "bench-response",
101+
srcs = ["bench-response.c++"],
102+
deps = [":test-fixture"],
103+
)
104+
99105
wd_test(
100106
src = "unknown-import-assertions-test.wd-test",
101107
args = ["--experimental"],
@@ -125,6 +131,7 @@ filegroup(
125131
":bench-kj-headers",
126132
":bench-mimetype",
127133
":bench-regex",
134+
":bench-response",
128135
":bench-text-encoder",
129136
":bench-util",
130137
],
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright (c) 2023 Cloudflare, Inc.
2+
// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3+
// https://opensource.org/licenses/Apache-2.0
4+
5+
#include <workerd/api/http.h>
6+
#include <workerd/tests/bench-tools.h>
7+
#include <workerd/tests/test-fixture.h>
8+
9+
// A benchmark for Response object construction to identify performance bottlenecks.
10+
11+
namespace workerd {
12+
namespace {
13+
14+
struct Response: public benchmark::Fixture {
15+
virtual ~Response() noexcept(true) {}
16+
17+
void SetUp(benchmark::State& state) noexcept(true) override {
18+
fixture = kj::heap<TestFixture>();
19+
}
20+
21+
void TearDown(benchmark::State& state) noexcept(true) override {
22+
fixture = nullptr;
23+
}
24+
25+
kj::Own<TestFixture> fixture;
26+
};
27+
28+
// Benchmark: Simple string body Response (most common case)
29+
// Pattern: new Response("Hello World")
30+
BENCHMARK_F(Response, simpleStringBody)(benchmark::State& state) {
31+
fixture->runInIoContext([&](const TestFixture::Environment& env) {
32+
auto& js = env.js;
33+
for (auto _: state) {
34+
auto body = api::Body::Initializer(kj::str("Hello World"));
35+
benchmark::DoNotOptimize(api::Response::constructor(js, kj::mv(body), kj::none));
36+
}
37+
});
38+
}
39+
40+
// Benchmark: Response with empty body (null)
41+
// Pattern: new Response(null, {status: 404})
42+
BENCHMARK_F(Response, nullBodyWithStatus)(benchmark::State& state) {
43+
fixture->runInIoContext([&](const TestFixture::Environment& env) {
44+
auto& js = env.js;
45+
for (auto _: state) {
46+
api::Response::InitializerDict init;
47+
init.status = 404;
48+
benchmark::DoNotOptimize(api::Response::constructor(js, kj::none, kj::mv(init)));
49+
}
50+
});
51+
}
52+
53+
// Benchmark: Response with headers
54+
// Pattern: new Response("body", {headers: {"Content-Type": "text/html"}})
55+
BENCHMARK_F(Response, bodyWithHeaders)(benchmark::State& state) {
56+
fixture->runInIoContext([&](const TestFixture::Environment& env) {
57+
auto& js = env.js;
58+
for (auto _: state) {
59+
api::Response::InitializerDict init;
60+
jsg::Dict<jsg::ByteString, jsg::ByteString> headersDict;
61+
headersDict.fields = kj::heapArray<jsg::Dict<jsg::ByteString, jsg::ByteString>::Field>(1);
62+
headersDict.fields[0].name = jsg::ByteString(kj::str("Content-Type"));
63+
headersDict.fields[0].value = jsg::ByteString(kj::str("text/html"));
64+
init.headers = kj::mv(headersDict);
65+
66+
auto body = api::Body::Initializer(kj::str("Hello World"));
67+
benchmark::DoNotOptimize(api::Response::constructor(js, kj::mv(body), kj::mv(init)));
68+
}
69+
});
70+
}
71+
72+
// Benchmark: Response with ArrayBuffer body
73+
// Pattern: new Response(arrayBuffer)
74+
BENCHMARK_F(Response, arrayBufferBody)(benchmark::State& state) {
75+
fixture->runInIoContext([&](const TestFixture::Environment& env) {
76+
auto& js = env.js;
77+
for (auto _: state) {
78+
auto bytes = kj::heapArray<byte>(11);
79+
memcpy(bytes.begin(), "Hello World", 11);
80+
auto body = api::Body::Initializer(kj::mv(bytes));
81+
benchmark::DoNotOptimize(api::Response::constructor(js, kj::mv(body), kj::none));
82+
}
83+
});
84+
}
85+
86+
// Benchmark: Response.json()
87+
// Pattern: Response.json({key: "value"})
88+
BENCHMARK_F(Response, jsonResponse)(benchmark::State& state) {
89+
fixture->runInIoContext([&](const TestFixture::Environment& env) {
90+
auto& js = env.js;
91+
for (auto _: state) {
92+
auto obj = js.obj();
93+
obj.set(js, js.str("key"_kj), js.str("value"_kj));
94+
benchmark::DoNotOptimize(api::Response::json_(js, obj, kj::none));
95+
}
96+
});
97+
}
98+
99+
} // namespace
100+
} // namespace workerd

0 commit comments

Comments
 (0)