Perf optimize cookie value validation#285
Conversation
a7aa0f0 to
2824b73
Compare
|
If more code is OK, an extra ~6% perf-increase can be achieved by replacing regex with a for-loop and individually checking function defaultEncode(str: string): string {
for (let i = 0, c = 0, len = str.length; i < len; i++) {
c = str.charCodeAt(i);
// \u0000-\u0020 (<33), \u007F-\uFFFF (>126), "(34), %(37), ,(44), ;(59), \(92)
if (c < 33 || c > 126 || c === 34 || c === 37 || c === 44 || c === 59 || c === 92)
return encodeURIComponent(str);
}
return str;
}Runtime:
I think with these we are getting into the "not so relevant speedup" territory, meaning code-readability should be prioritised instead. If you read and understand regex more easily, then that is preferable than above for-loop! |
|
And for completion, here also the other regexes in for-loop form, gaining ~10% more (at least with the current bench, we might want to test with longer strings): function validCookieName(str: string): boolean {
for (let i = 0, c = 0, len = str.length; i < len; i++) {
c = str.charCodeAt(i);
// ;(59) =(61)
if (c < 33 || c > 126 || c === 59 || c === 61)
return false;
}
return true;
}
function validCookieValue(str: string): boolean {
for (let i = 0, c = 0, len = str.length; i < len; i++) {
c = str.charCodeAt(i);
// ;(59)
if (c < 33 || c > 126 || c === 59) return false;
}
return true;
}
function validCookiePath(str: string): boolean {
for (let i = 0, c = 0, len = str.length; i < len; i++) {
c = str.charCodeAt(i);
// ;(59) <(60)
if (c < 32 || c > 126 || c === 59 || c === 60) return false;
}
return true;
}And in case wanted to add a bit more readability, we can generate the const EXLAMATION = '!'.charCodeAt(0)
const DOUBLEQUOTE = '"'.charCodeAt(0)
const PERCENT = '%'.charCodeAt(0)
const COMMA = ','.charCodeAt(0)
const SEMICOLON = ';'.charCodeAt(0)
const LESS_THAN = '<'.charCodeAt(0)
const EQUAL = '='.charCodeAt(0)
const BACKSLASH = '\\'.charCodeAt(0)
const TILDE = '~'.charCodeAt(0) |
|
Walking back on my suggestion... For-loop perf improvement only happens when the invalid / encoding-required character is found within the first ~15 characters. By the time it's 512 chars, for-loop is twice as slow. Meaning for-loop is still faster for longer strings, if for example |
Tweak encoder regex to be a negative class match (benchmark is slightly faster, but marginal, could undo if someone really disagrees) and skips validation of the value entirely when using the default encoder since it's already known valid.