diff options
author | Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> | 2024-08-01 17:30:26 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-02 00:30:26 +0000 |
commit | 930ccf928aee3ce5befc0a7494e0f9caaf0c8c63 (patch) | |
tree | 385b4f2602cdd7a8250f25e86db4f408c6d313c9 /ext/http/service.rs | |
parent | 5c54dc5840e26410e364619b73b4721ce1815cef (diff) |
perf(ext/http): Reduce size of `ResponseBytesInner` (#24840)
I noticed
[`set_response_body`](https://github.com/nathanwhit/deno/blob/ce42f82b5a985e5f1482dff97a7268019a8e79ea/ext/http/service.rs#L439-L443)
was unexpectedly hot in profiles, with most of the time being spent in
`memmove`.
It turns out that `ResponseBytesInner` was _massive_ (5624 bytes), so
every time we moved a `ResponseBytesInner` (for instance in
`set_response_body`) we were doing a >5kb memmove, which adds up pretty
quickly.
This PR boxes the two larger variants (the compression streams),
shrinking `ResponseBytesInner` to a reasonable 48 bytes.
---
Benchmarked with a simple hello world server:
```ts
// hello-server.ts
Deno.serve((_req) => {
return new Response("Hello world");
});
// run with `deno run -A hello-server.ts`
// in separate terminal `wrk -d 10s http://127.0.0.1:8000`
```
Main:
```
Running 10s test @ http://127.0.0.1:8000/
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 53.39us 9.53us 0.98ms 92.78%
Req/Sec 86.57k 3.56k 91.58k 91.09%
1739319 requests in 10.10s, 248.81MB read
Requests/sec: 172220.92
Transfer/sec: 24.64MB
```
This PR:
```
Running 10s test @ http://127.0.0.1:8000/
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 45.44us 8.49us 0.91ms 90.04%
Req/Sec 100.65k 2.26k 102.65k 96.53%
2022296 requests in 10.10s, 289.29MB read
Requests/sec: 200226.20
Transfer/sec: 28.64MB
```
So a nice ~15% bump. (With response body compression, the gain is ~10%
for gzip and neutral for brotli)
Diffstat (limited to 'ext/http/service.rs')
-rw-r--r-- | ext/http/service.rs | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/ext/http/service.rs b/ext/http/service.rs index f38fec4f4..787e9babf 100644 --- a/ext/http/service.rs +++ b/ext/http/service.rs @@ -545,10 +545,10 @@ impl Body for HttpRecordResponse { ready!(Pin::new(stm).poll_frame(cx)) } ResponseBytesInner::GZipStream(stm) => { - ready!(Pin::new(stm).poll_frame(cx)) + ready!(Pin::new(stm.as_mut()).poll_frame(cx)) } ResponseBytesInner::BrotliStream(stm) => { - ready!(Pin::new(stm).poll_frame(cx)) + ready!(Pin::new(stm.as_mut()).poll_frame(cx)) } }; // This is where we retry the NoData response |