Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(web): ~400x faster http header trimming #12277

Merged
merged 5 commits into from
Sep 30, 2021

Conversation

AaronO
Copy link
Contributor

@AaronO AaronO commented Sep 30, 2021

Use a regex substring match with a first/last char fastpath instead of 2 regex replaces. Roughly ~400x faster (423ms vs 0.7ms in profiled runs)

Use a regex substring match vs 2 replaces. Roughly ~1.65x faster (423ms vs 255ms in profiled runs)
Check first and and last chars before running regex so already trimmed values are fast, this reduces httpTrims cost from ~255ms => 0.7ms in profiled runs
@AaronO AaronO changed the title perf(web): faster http header trimming perf(web): ~400x faster http header trimming Sep 30, 2021
@aapoalas
Copy link
Collaborator

LGTM. Only possible improvement I could see is to check do the substring manually as well. Something like this:

const needsTrimStart = isHttpWhitespace(str[0]);
const needsTrimEnd = isHttpWhitespace(str[str.length - 1]);
if (!needsTrimStart && !needsTrimEnd) return str;

let startIndex = Number(needsTrimStart);
if (needsTrimStart) {
  startIndex = getFirstNonHttpWhitespaceIndex(startIndex);
}
let endIndex = needsTrimEnd ? getLastNonHttpWhitespaceIndex(str.length - 2) : undefined;
return str.substring(startIndex, endIndex);

@AaronO
Copy link
Contributor Author

AaronO commented Sep 30, 2021

LGTM. Only possible improvement I could see is to check do the substring manually as well. Something like this:

const needsTrimStart = isHttpWhitespace(str[0]);
const needsTrimEnd = isHttpWhitespace(str[str.length - 1]);
if (!needsTrimStart && !needsTrimEnd) return str;

let startIndex = Number(needsTrimStart);
if (needsTrimStart) {
  startIndex = getFirstNonHttpWhitespaceIndex(startIndex);
}
let endIndex = needsTrimEnd ? getLastNonHttpWhitespaceIndex(str.length - 2) : undefined;
return str.substring(startIndex, endIndex);

Had considered that too, but I'm happy mainly optimizing for the fast-path of no trimming right now since that should be the the dominant path too

@aapoalas
Copy link
Collaborator

Had considered that too, but I'm happy mainly optimizing for the fast-path of no trimming right now since that should be the the dominant path too

Makes sense.

Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@AaronO AaronO merged commit 68e5cda into denoland:main Sep 30, 2021
@AaronO AaronO deleted the perf/web-http-trim branch September 30, 2021 16:39
ry pushed a commit that referenced this pull request Oct 4, 2021
Use a regex substring match with a first/last char fastpath instead of 2 regex replaces. Roughly ~400x faster (423ms vs 0.7ms in profiled runs)
"",
);
return potentialValue;
return httpTrim(potentialValue);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Sorry about my ignorance, but why not just move the entire content of httpTrim to normalizeHeaderValue function? That'd remove httpTrim definition everywhere which is a lot of lines less with the same result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants