diff options
author | Marcos Casagrande <marcoscvp90@gmail.com> | 2023-08-10 19:45:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-10 19:45:55 +0200 |
commit | 6b1a9761812c2f373e52684ae4be8fb939e589b7 (patch) | |
tree | 225cdc5a8319c717f5e32033f7d99d8a34661b16 /ext/http/00_serve.js | |
parent | 2d3d0a579d8c3c5f038470e2c6610f6d44d29eb0 (diff) |
perf(ext/http): use ServeHandlerInfo class instead of object literal (#20122)
This PR improves performance of `Deno.Serve` when providing `info`
argument by creating `ServeHandlerInfo` class instead of creating an
object literal with a getter on every request.
```js
Deno.serve((_req, info) => new Response(info.remoteAddr.transport) });
```
### Benchmarks
```
wrk -d 10s --latency http://127.0.0.1:4500
Running 10s test @ http://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 42.34us 16.30us 1.66ms 95.88%
Req/Sec 118.17k 2.95k 127.38k 76.73%
Latency Distribution
50% 38.00us
75% 41.00us
90% 56.00us
99% 83.00us
2375298 requests in 10.10s, 319.40MB read
Requests/sec: 235177.04
Transfer/sec: 31.62MB
```
**main**
```
wrk -d 10s --latency http://127.0.0.1:4500
Running 10s test @ http://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 78.86us 211.06us 3.58ms 96.52%
Req/Sec 105.90k 4.35k 117.41k 78.22%
Latency Distribution
50% 41.00us
75% 53.00us
90% 62.00us
99% 1.18ms
2127534 requests in 10.10s, 286.09MB read
Requests/sec: 210647.49
Transfer/sec: 28.33MB
```
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.0 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
-------------------------------------------------------------------------- -----------------------------
new ServeHandlerInfo 3.43 ns/iter 291,508,889.3 (3.07 ns … 12.21 ns) 3.42 ns 3.84 ns 3.87 ns
{} with getter 133.84 ns/iter 7,471,528.9 (92.9 ns … 458.95 ns) 132.45 ns 364.96 ns 429.43 ns
```
----
### Drawbacks:
`.remoteAddr` is now not enumerable
```
ServeHandlerInfo {}
```
vs
```
{ remoteAddr: [Getter] }
```
It'll break any code trying to iterate through `info` keys (Doubt
there's anyone doing it though)
```js
Deno.serve((req, info) => {
console.log(Object.keys(info).length === 0) // true;
return new Response("yes");
});
Diffstat (limited to 'ext/http/00_serve.js')
-rw-r--r-- | ext/http/00_serve.js | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js index af4353e0e..3447f48e2 100644 --- a/ext/http/00_serve.js +++ b/ext/http/00_serve.js @@ -369,6 +369,16 @@ class CallbackContext { } } +class ServeHandlerInfo { + #inner = null; + constructor(inner) { + this.#inner = inner; + } + get remoteAddr() { + return this.#inner.remoteAddr; + } +} + function fastSyncResponseOrStream(req, respBody) { if (respBody === null || respBody === undefined) { // Don't set the body @@ -535,11 +545,10 @@ function mapToCallback(context, callback, onError) { if (hasOneCallback) { response = await callback(request); } else { - response = await callback(request, { - get remoteAddr() { - return innerRequest.remoteAddr; - }, - }); + response = await callback( + request, + new ServeHandlerInfo(innerRequest), + ); } } else { response = await callback(); |