From 37c983d1e8e83fd2b381028d37f6358df1fa4513 Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Thu, 19 Aug 2021 13:41:47 +0200 Subject: [PATCH] perf(ext/url): optimize UrlParts op serialization (#11765) --- ext/url/00_url.js | 40 +++++++++++++++++++++++++++---- ext/url/lib.rs | 61 +++++++++++++++++++++++++---------------------- 2 files changed, 69 insertions(+), 32 deletions(-) diff --git a/ext/url/00_url.js b/ext/url/00_url.js index 33235f9342..805a61329d 100644 --- a/ext/url/00_url.js +++ b/ext/url/00_url.js @@ -40,9 +40,41 @@ const SET_SEARCH = 8; const SET_USERNAME = 9; - // Helper function + // Helper functions function opUrlReparse(href, setter, value) { - return core.opSync("op_url_reparse", href, [setter, value]); + return _urlParts(core.opSync("op_url_reparse", href, [setter, value])); + } + function opUrlParse(href, maybeBase) { + return _urlParts(core.opSync("op_url_parse", href, maybeBase)); + } + function _urlParts(internalParts) { + // WARNING: must match UrlParts serialization rust's url_result() + const { + 0: href, + 1: hash, + 2: host, + 3: hostname, + 4: origin, + 5: password, + 6: pathname, + 7: port, + 8: protocol, + 9: search, + 10: username, + } = internalParts.split("\n"); + return { + href, + hash, + host, + hostname, + origin, + password, + pathname, + port, + protocol, + search, + username, + }; } class URLSearchParams { @@ -289,7 +321,7 @@ }); } this[webidl.brand] = webidl.brand; - this[_url] = core.opSync("op_url_parse", url, base); + this[_url] = opUrlParse(url, base); } [SymbolFor("Deno.privateCustomInspect")](inspect) { @@ -401,7 +433,7 @@ prefix, context: "Argument 1", }); - this[_url] = core.opSync("op_url_parse", value); + this[_url] = opUrlParse(value); this.#updateSearchParams(); } diff --git a/ext/url/lib.rs b/ext/url/lib.rs index 25ecc1358c..d8987c816f 100644 --- a/ext/url/lib.rs +++ b/ext/url/lib.rs @@ -11,7 +11,6 @@ use deno_core::url::quirks; use deno_core::url::Url; use deno_core::Extension; use deno_core::ZeroCopyBuf; -use serde::Serialize; use std::panic::catch_unwind; use std::path::PathBuf; @@ -36,20 +35,23 @@ pub fn init() -> Extension { .build() } -#[derive(Serialize)] -pub struct UrlParts { - href: String, - hash: String, - host: String, - hostname: String, - origin: String, - password: String, - pathname: String, - port: String, - protocol: String, - search: String, - username: String, -} +// UrlParts is a \n joined string of the following parts: +// #[derive(Serialize)] +// pub struct UrlParts { +// href: String, +// hash: String, +// host: String, +// hostname: String, +// origin: String, +// password: String, +// pathname: String, +// port: String, +// protocol: String, +// search: String, +// username: String, +// } +// TODO: implement cleaner & faster serialization +type UrlParts = String; /// Parse `UrlParseArgs::href` with an optional `UrlParseArgs::base_href`, or an /// optional part to "set" after parsing. Return `UrlParts`. @@ -137,19 +139,22 @@ fn url_result( )) })?; - Ok(UrlParts { - href: quirks::href(&url).to_string(), - hash: quirks::hash(&url).to_string(), - host: quirks::host(&url).to_string(), - hostname: quirks::hostname(&url).to_string(), - origin: quirks::origin(&url), - password: quirks::password(&url).to_string(), - pathname: quirks::pathname(&url).to_string(), - port: quirks::port(&url).to_string(), - protocol: quirks::protocol(&url).to_string(), - search: quirks::search(&url).to_string(), - username: username.to_string(), - }) + Ok( + [ + quirks::href(&url), + quirks::hash(&url), + quirks::host(&url), + quirks::hostname(&url), + &quirks::origin(&url), + quirks::password(&url), + quirks::pathname(&url), + quirks::port(&url), + quirks::protocol(&url), + quirks::search(&url), + username, + ] + .join("\n"), + ) } pub fn op_url_parse_search_params(