3 ms·
As someone who's been writing a lot of JavaScript, Go, and a handful of other languages for a while, I feel this. In Go, I can basically know what's going to ha
by connor4312 7y ago
As someone who's been writing a lot of JavaScript, Go, and a handful of other languages for a while, I feel this. In Go, I can basically know what's going to happen when I write a function. This operation will read from the stack, these instructions will be run, and I can take a peek at the assembly if I'm not sure (though I've developed a pretty good feel for what Go will do without needing that). I can benchmark it and know that the performance I see on my machine will be the performance when I ship this bit of functionality into production, barring hardware differences.
In JavaScript, it's a black box. I know some constructs might deoptimize functions when run on Wednesdays because I read them on a blog published in 2018 that's _probably_ still accurate. In my benchmark running on Node 12.14.1 on Windows this seems to be true. But then who knows if it'll be the same thing in production, and it might 'silently' change later on.
JavaScript in V8 is incredibly fast these days, but I find it much easier to write optimal code in Go.
- _bxg1 7y agoIt's really no different from native compiler optimizations, which are also mysterious and always changing, except for one key aspect: when recording timings to compare against other timings, you can control whether optimizations are turned on or off, to remove that variable from the comparison.
- lpghatguy 7y agoThankfully, with a native compiler you don't have to deal with your JIT warming up, or some other code causing your function to get deoptimized, or subtle JIT trace aborts. :(
- fctorial 7y ago> or some other code causing your function to get deoptimized Why doesn't the optimizer generate different compiled implementations of a function for different pieces of code?
- notamy 7y agoI would imagine this to be due to the overhead of then having to track where EVERY variant of a JITted function can then be called from, when to deoptimize, etc.
- pjmlp 7y agoInstead you have to deal with the myriad of optimization flags, optimizations that take advantage of UB and change between versions regarding C and C++ compilers, inlines being dropped because a bug correction made the function body bigger than the allowed threshold,...
- saagarjha 7y ago> It's really no different from native compiler optimizations, which are also mysterious and always changing Go’s compiler is kind of stupid in this sense.
- erik_seaberg 7y agoJavascript lets you work at a pretty high level, and tries to fill in a reasonable implementation, but you can't be sure how its choices will perform. Go (like C) forces you to dictate the exact implementation in painful detail without abstracting away much of anything, which might be a reasonable tradeoff for very hot paths but not the entire system.
- mst 7y agoThis seems a little unfair, given while the compiler is an even bigger pedant than I am, Rust does allow you to abstract away quite a lot of stuff and still get performant results.
- erik_seaberg 7y agoI like Rust for reusable low-cost abstractions, but using it professionally seems to require an employer with a lot more trust in their team than usual.
- gridlockd 7y ago> In JavaScript, it's a black box. You can actually look at the assembly generated by V8 and you can trace de-opts. The workflow is just so awful, you're not going to want to do it.
- pjmlp 7y agoI really hate that one just isn't able to provide a basic -S or similar switch.