var TestString = '+'.repeat(200) + '='.repeat(20000) + '+'.repeat(200);
function regexTrim(str, what) {
const chars = [ (what ? what : '\0\t\n\v\r ')].map((c) => ([']', '^', '\\', '-'].includes(c) ? '\\' + c : c)).join('');
return str.replace(new RegExp('^[' + chars + ']+|[' + chars + ']+$', 'gu'), '');
}
function indexTrim(str, what) {
let end, start;
const chars = [str];
const charsToTrim = [ (what ? what : '\0\t\n\v\r ')];
start = 0;
end = chars.length;
while (start < end && charsToTrim.includes(chars[start])) {
++start;
}
while (end > start && charsToTrim.includes(chars[end - 1])) {
--end;
}
return (start > 0 || end < chars.length) ? chars.slice(start, end).join('') : str.slice();
}
function booleanTrim(str, what) {
let result;
const chars = what ? what : '\0\t\n\v\r ';
result = str;
for (const c of chars) {
result = result.split(c).filter(Boolean).join(c);
}
return result;
}
function spreadTrim(str, what) {
const chars = [str];
const charsToTrim = [ (what ? what : '\0\t\n\v\r ')];
const end = chars.reverse().findIndex((c) => !charsToTrim.includes(c));
const start = chars.reverse().findIndex((c) => !charsToTrim.includes(c));
return chars.slice(start, chars.length - end).join('');
}
function substringTrim(str, what) {
const chars = what ? what : '\0\t\n\v\r ';
while (chars.includes(String.fromCodePoint(str.codePointAt(0)))) {
str = str.substring(1);
}
while (chars.includes(String.fromCodePoint(str.codePointAt(str.length - 1)))) {
str = str.substring(0, str.length - 1);
}
return str;
}
function sliceTrim(str, what) {
const chars = what ? what : '\0\t\n\v\r ';
while (chars.includes(String.fromCodePoint(str.codePointAt(0)))) {
str = str.slice(1);
}
while (chars.includes(String.fromCodePoint(str.codePointAt(str.length - 1)))) {
str = str.slice(0, -1);
}
return str;
}
regexTrim(TestString, '+');
indexTrim(TestString, '+')
booleanTrim(TestString, '+')
spreadTrim(TestString, '+')
substringTrim(TestString, '+')
sliceTrim(TestString, '+')
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Regex Trim | |
Index Trim | |
Boolean Filter Trim | |
Spread Trim | |
Substring Trim | |
Slice Trim |
Test name | Executions per second |
---|---|
Regex Trim | 75229.6 Ops/sec |
Index Trim | 1217.8 Ops/sec |
Boolean Filter Trim | 33609.3 Ops/sec |
Spread Trim | 1209.1 Ops/sec |
Substring Trim | 25610.1 Ops/sec |
Slice Trim | 26697.0 Ops/sec |
Let's dive into the world of JavaScript microbenchmarks on MeasureThat.net.
The provided benchmark definition json represents six different algorithms for trimming leading/trailing characters from a string:
regexTrim
: uses regular expressions to remove charactersindexTrim
: iterates over the string and removes characters manuallybooleanTrim
: uses boolean filtering to remove charactersspreadTrim
: spreads the characters in the opposite order and finds the index of the first/last character that is not removedsubstringTrim
: removes characters from the start/end of the string until a certain character is foundsliceTrim
: uses slicing to remove characters from the start/end of the stringNow, let's compare these approaches:
Regex Trim (regexTrim):
* Pros: efficient, works well for most cases
* Cons: can be slow for very large strings or complex regular expressions
* Considerations: the regex pattern used can significantly impact performance. The use of anchors (^
and $
) and character classes ([]
) can improve efficiency.
Index Trim (indexTrim): * Pros: simple, easy to understand, works well for small-medium size strings * Cons: slow for large strings, may cause stack overflow for very long strings * Considerations: this approach is sensitive to the string's length and character set. The use of manual iteration can lead to performance issues.
Boolean Filter Trim (booleanTrim): * Pros: simple, easy to understand, works well for small-medium size strings * Cons: slow for large strings, may cause stack overflow for very long strings * Considerations: this approach uses a lot of memory and CPU cycles due to the repeated boolean checks.
Spread Trim (spreadTrim): * Pros: efficient, works well for most cases * Cons: can be slow for very large strings or complex spreads * Considerations: the spread operation is relatively fast, but may cause issues with very long strings.
Substring Trim (substringTrim): * Pros: efficient, works well for most cases * Cons: can be slow for very large strings or complex substrings * Considerations: the use of substring methods can lead to performance issues if not optimized properly.
Slice Trim (sliceTrim): * Pros: efficient, works well for most cases * Cons: can be slow for very large strings or complex slicing * Considerations: the slice operation is relatively fast, but may cause issues with very long strings.
Now, let's look at the latest benchmark results. The browsers used are Firefox 94 on a Mac OS X 10.15 desktop. The results show that:
regexTrim
performs well, with high execution rates across all devices.indexTrim
and booleanTrim
perform poorly due to their slow execution rates.spreadTrim
, substringTrim
, and sliceTrim
have similar performance profiles, with spreadTrim
being slightly faster in some cases.Overall, the choice of algorithm depends on the specific use case and requirements. If speed is critical, regexTrim
or spreadTrim
might be a good choice. However, if memory usage or CPU cycles are a concern, indexTrim
or booleanTrim
might be better suited for smaller strings.