See https://bugzilla.mozilla.org/show_bug.cgi?id=705597#c51 to #c53. It's odd that "s.indexOf(c) == 0" is faster than the alternatives, since it has to do more work. We should optimize at least one of the following, and maybe all of them, down to some guards followed by a strcmp. if (s.indexOf("about:") == 0) In a simple implementation, this scans the entire string. It's currently the fastest! if (/^about:/.test(s)) In a simple implementation, this creates a regexp each time through the loop, along with updating regexp statics. if (s.substr(0, 6) == "about:") In a simple implementation, this allocates a new string before comparing.
The best candidate to optimize here is the /^literal/.test version --- fewer moving parts, and we already avoid the regexp cloning (using TI to determine the cloned regexp won't escape). We still go through the regexp machinery though. Is bug 705597 running chrome or content code? TI is turned off in chrome code, and non-compileAndGo (chrome) stuff is generally a good deal slower than compileAndGo (content) stuff in JM, for various reasons. We will get parity between the two with compartment-per-global (which will make all code compileAndGo).
Bug 705597 is chrome (sessionstore code) which runs every few seconds if you're active, generally, and currently blocks the main ui thread.
Depends on: 650353
Summary: Sane methods of checking which strings start with a (constant) string are slow → Sane methods of checking which strings start with a (constant) string are slow in chrome code
ES6 will have String.prototype.startsWith :) http://blog.cdleary.com/2012/01/accomplish-your-new-years-resolution-of-being-more-badass/
A trick from bug 728780: if (s.lastIndexOf("about", 0) === 0) The second param to lastIndexOf is the key: it says to start searching backwards from the beginning of the string.
startsWith landed quite some time ago. Can we close this now? Is it as fast as indexOf() == 0?
(In reply to Tim Taubert [:ttaubert] (on PTO, back Mon Sep 9th) from comment #5) > startsWith landed quite some time ago. Can we close this now? Is it as fast > as indexOf() == 0? Quick micro-benchmark shows it's faster than indexOf / lastIndexOf(.., 0), so let's close this.
Status: NEW → RESOLVED
Last Resolved: 5 years ago
Resolution: --- → FIXED
FYI, we have ~30 uses in a trivial 'jsfind "ndexOf" | grep 0 | grep == | wc' (jsfind ~= find -name "*.js[m]" | xargs grep $*) JSM files: Most are in devtools and likely not critical (though would be nice to fix, most are in gcli). The real ones are in SourceMap.jsp, PhoneNumber.jsm, Webapps.jsm, WspPduHelper.jsm, MmsPduHelper.jsm, utils.jsm and PlacesDBUtils.jsm In js files there are a lot more. A ton in tests, but also WifiWorker.js, android chrome, places, microformats, etc. An estimate using grep -v to eliminate tests, etc got ~100. We should fix any cases that might actually affect performance, and publicize this on MDN in the docs for indexOf/etc.
You need to log in before you can comment on or make changes to this bug.