Skip to content

Commit b095157

Browse files
authored
perf(ext/fetch): Use the WebIDL conversion to DOMString rather than USVString for Response constructor (denoland#12201)
1 parent 09f2cdb commit b095157

File tree

5 files changed

+48
-6
lines changed

5 files changed

+48
-6
lines changed

cli/bench/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ const EXEC_TIME_BENCHMARKS: &[(&str, &[&str], Option<i32>)] = &[
111111
&["run", "cli/tests/testdata/text_encoder_into_perf.js"],
112112
None,
113113
),
114+
(
115+
"response_string",
116+
&["run", "cli/tests/testdata/response_string_perf.js"],
117+
None,
118+
),
114119
(
115120
"check",
116121
&[
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const mixed = "@Ā๐😀";
2+
3+
function generateRandom(bytes) {
4+
let result = "";
5+
let i = 0;
6+
while (i < bytes) {
7+
const toAdd = Math.floor(Math.random() * Math.min(4, bytes - i));
8+
switch (toAdd) {
9+
case 0:
10+
result += mixed[0];
11+
i++;
12+
break;
13+
case 1:
14+
result += mixed[1];
15+
i++;
16+
break;
17+
case 2:
18+
result += mixed[2];
19+
i++;
20+
break;
21+
case 3:
22+
result += mixed[3];
23+
result += mixed[4];
24+
i += 2;
25+
break;
26+
}
27+
}
28+
return result;
29+
}
30+
31+
const randomData = generateRandom(1024);
32+
for (let i = 0; i < 10_000; i++) {
33+
new Response(randomData);
34+
}

ext/fetch/22_body.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@
372372
return { body, contentType };
373373
}
374374

375-
webidl.converters["BodyInit"] = (V, opts) => {
375+
webidl.converters["BodyInit_DOMString"] = (V, opts) => {
376376
// Union for (ReadableStream or Blob or ArrayBufferView or ArrayBuffer or FormData or URLSearchParams or USVString)
377377
if (V instanceof ReadableStream) {
378378
// TODO(lucacasonato): ReadableStream is not branded
@@ -393,10 +393,13 @@
393393
return webidl.converters["ArrayBufferView"](V, opts);
394394
}
395395
}
396-
return webidl.converters["USVString"](V, opts);
396+
// BodyInit conversion is passed to extractBody(), which calls core.encode().
397+
// core.encode() will UTF-8 encode strings with replacement, being equivalent to the USV normalization.
398+
// Therefore we can convert to DOMString instead of USVString and avoid a costly redundant conversion.
399+
return webidl.converters["DOMString"](V, opts);
397400
};
398-
webidl.converters["BodyInit?"] = webidl.createNullableConverter(
399-
webidl.converters["BodyInit"],
401+
webidl.converters["BodyInit_DOMString?"] = webidl.createNullableConverter(
402+
webidl.converters["BodyInit_DOMString"],
400403
);
401404

402405
window.__bootstrap.fetchBody = { mixinBody, InnerBody, extractBody };

ext/fetch/23_request.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@
445445
{
446446
key: "body",
447447
converter: webidl.createNullableConverter(
448-
webidl.converters["BodyInit"],
448+
webidl.converters["BodyInit_DOMString"],
449449
),
450450
},
451451
{ key: "redirect", converter: webidl.converters["RequestRedirect"] },

ext/fetch/23_response.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@
253253
*/
254254
constructor(body = null, init = {}) {
255255
const prefix = "Failed to construct 'Response'";
256-
body = webidl.converters["BodyInit?"](body, {
256+
body = webidl.converters["BodyInit_DOMString?"](body, {
257257
prefix,
258258
context: "Argument 1",
259259
});

0 commit comments

Comments
 (0)