Just look at JavaScript. Dozens of libraries that do the same thing, a vibrant ecosystem as a result.
Just look at JavaScript. Dozens of libraries that do the same thing, a vibrant ecosystem as a result.
Chakra and SpiderMonkey fully optimize these functions even with a try/catch statement (according to 2 devs last time I talked about this [2]).
Without alternate engines, people start to think that implementation details in one engine apply to javascript as a whole.
Just look around at most javascript "performance tips". Most of them talk about how you should avoid try/catch in performant code, even though it's only one engine that doesn't optimize it, and they have talked about how they want to fix it, but just haven't [3].
And that's just one example, there are hundreds of examples of bugs, performance tricks, and even differences in spec interpretation that can cause issues and can inadvertently become a "standard" without multiple competing engines.
[1] More accurately, the function will never be optimized in the first place if it contains a try/catch at all since Crankshaft doesn't support try/catch.
[2] https://news.ycombinator.com/item?id=10896729
[3] IIRC they haven't devoted time to optimizing it because the architecture of V8 doesn't work well with something like try/catch, but also because it's fairly simple to work around, and most people already do. So you kind of get a catch 22 where V8 won't spend time to fix it because it's not worth it, and it won't be worth it because V8 doesn't support it.
That's an easy fix though: introduce one or more performance tests that stress try/catch (i.e. don't employ the workaround). Obviously Google won't be doing it, but there's nothing to stop Microsoft or Mozilla for lobbying for it.
That seems like a non-trivial task. Though luckily (for the JS community) they've been working on it.
Happily, they've thought about this stuff already:
"Continuing to invest in understanding and improving real world performance is a priority for the team. Going forward, we also want to work with the benchmarking workgroup[0] and the community to identify real world performance scenarios for Node.js." [1]
[0] - https://github.com/nodejs/benchmarking
[1] - https://blogs.windows.com/msedgedev/2016/01/19/nodejs-chakra...
> Most of them talk about how you should avoid try/catch in
> performant code, even though it's only one engine that doesn't
> optimize it
That still sounds like great advice even though it's "only" slow on
one engine. Very few performant JS applications have the luxury of not
worrying about how Chrome performs, as opposed to only IE, Firefox &
Safari.My point was that you want multiple competing engines to avoid this kind of thing going from a "V8 thing" to a "Javascript thing".
Right now V8 can still fix this "issue" and going forward that will no longer be a problem, but if history was a little different, we could have ended up with no engines that support an optimized try/catch since nobody uses it, and nobody would use it because no engines supported optimizing it.
If Microsoft had released Chakra around the same time, it never would've been an issue, because people would've known "Oh, this is just Google's bug", gotten on their case to fix it, and it would've been gone a long time ago.
But this is the exact situation that the browser world is in (V8 is only one vendor among many) and that hasn't come to pass.
Safari has become the new IE in a lot of ways, and larger and larger websites/apps are starting to only target Firefox and Chrome, leaving Apple with the options to either give up or rejoin the mainstream.
Wasn't the workaround to do nothing in the try/catch body aside from calling a named function defined outside the function scope where the try/catch was defined?
It's fixed in Turbofan, but that's not shipping yet.
Well, if that engine is dominant or even just a 20%+ player (like V8 is), the advice still holds, whether there are 2 or 5 other engines.
Disclaimer: I work on the V8 team.
var times = [[],[]]
var sums = [0, 0]
var funcs = [
function(){ sums[0]+=1 },
function(){try{ sums[1]+=1 }catch(e){}}
]
function bench(n){
var t0 = performance.now()
for(var i = 0; i< 30000; i++) funcs[n]()
times[n].push(performance.now()-t0)
}
for(var j = 0; j< 10000; j++) bench(j%2)
function avg(ary){return ary.reduce(function(acc, v){return acc+v}, 0)/ary.length}
console.log(times.map(avg))
// results:
// [bare , wrapped in try{} ]
// VM89:18 [0.347546000033617, 0.7464809999451041]
Let's do some more work inside the function / try block: var times = [[],[]]
var sums = [0, 0]
var funcs = [
function(){ for (var i = 0; i < 1000; i++) sums[0]+=1 },
function(){try{ for (var i = 0; i < 1000; i++) sums[1]+=1 }catch(e){}}
]
function bench(n){
var t0 = performance.now()
for(var i = 0; i< 30; i++) funcs[n]()
times[n].push(performance.now()-t0)
}
for(var j = 0; j< 10000; j++) bench(j%2)
function avg(ary){return ary.reduce(function(acc, v){return acc+v}, 0)/ary.length}
console.log(times.map(avg))
// results:
// [bare , wrapped in try{} ]
// VM90:18 [0.09457900004982948, 0.5069960000008344]
I'm sure I'm doing many things wrong since I'm not a JS perf expert, but still, the difference here is goes from 2 to 50 times slower with the `try` block...Edit: for the sake of completeness, on the same machine:
Firefox gives [10.2, 10.3] and [5.30, 5.45]
Safari gives [5.56, 5.60] and [4.91, 4.94]