This is actually almost completely wrong information. The lower-level for loop is much more JS engine friendly than the Array methods (filter, map etc.). So unless you write JS like it's C, for the most part, CoffeeScript will probably generate more efficient code[1]. As shown in the jsperf by @mischani [2]
The only thing that's true is that CofeeScript generates some throwaway code because of implicit returns and the "everything is an expression" rule. However, I doubt that they would cause much overhead, specially with modern JS engines optimisation capabilities.
See my other comment. I too think that using .map, .filter, and .forEach are a bad idea. But also, if you see the code I would have written in the jsperf, I'd guess you say that I write JS like it's C.
* Every time I load the JSPerf page on Firefox, the first run the two tests are on par, and the second (and following) runs I get map being much slower. I have to wonder if the JS engine begins optimizing the comprehension version at some point.
Function calls in JavaScript runtimes (including V8) are quite slow. Array.map/filter/forEach will always be slower than a for loop doing the same thing.
I write a lot of games and game related things in JavaScript, and this is actually a major reason why I now use CoffeeScript. Nice clean comprehension syntax and better performance.
Array.map/filter/forEach aren't just slow because of function call overhead. They have different semantics than the for loop that you'd typically write (and that Coffeescript generates), because they support things like arrays with non-incremental keys. See the reference implementation at [1].
I was going to say... I thought one of the major selling points of CoffeeScript was that it outputs JavaScript that is highly optimized for JS interpreters.
Can you run a test with the code in the article?
I even said: "And that's still not ideal. We should be able to do: [code]".
I don't ever advise using map, but you can't setup your own for loop in coffeescript. Actually, in the code shown, map isn't used at all. Just .filter and .forEach.
There's no evidence presented here that there's any significant (or even negative) performance impact from the way the CoffeeScript compiles these list comprehensions. Also, if your performance is constrained by a list comprehension, there's nothing in CoffeeScript preventing you from using "Array.filter" instead. By and large CoffeeScript compiles one-to-one with JavaScript and when it doesn't, the resulting code is at least reasonably performant.
I do agree that the default return behavior is probably a bad idea. It probably came from Ruby, and I can see the appeal, but I've often created bugs by accidentally using the implicit return, then adding something to the end of a function. It's not really that big of a deal - I just as a policy always use an explicit return.
Also as an aside, CoffeeScript will only bother to populate the results array if the comprehension is the last thing in the function. If there is anything else that follows and you never use the result of the comprehension, then it compiles into a simple for loop. This is because CoffeeScript can't know if you actually plan to take advantage of its implicit return in this case.
I have found I've been forced to add a dummy `return` at the end of some of my CS methods because of this. It's one of only a very few complaints I have with the language.
fwiw, I love coffeescript. I write a game a few weeks ago in it, but I've never shown it to anyone before. Have a look here if you're interested http://quietcode.com/vectroid
I've made no attempts at all at performance tuning yet it runs very nicely in webkit browsers and not too bad in firefox.
Wave 7 - 327950, no deaths, got bored and quit first try. It's too easy! You should add difficulty levels. (I played a lot of Touhou recently so my sense of "difficult" is in a non-standard location.) Also, more enemies that shoot things that can't be destroyed, and enemies/asteroids that need multiple hits to die (maybe enemy health increases for higher difficulty / later waves).
Bugs I noticed: All the bullets in the world sometimes disappear at once. There's no pause button.
Mostly I love the controls, except friction on your ship is a little aggressive -- I think there should be no friction if you're below a certain speed, but maybe it's just my expectations from Star Control 2 (check out the FOSS version, Ur-quan Masters, with sudo apt-get install uqm if you're on an Ubuntu-like system). Also, the game desperately needs a hold-to-fire, or even toggle fire, button. Single-shot fire in a game like this is why there was a thriving turbo controller cottage industry in the '80s - '90s.
Yes, I was trying to reward the player for flying faster instead of just sitting on one spot. Projectile speed increases as your speed increases. I though damaging your own ship would just be cruel :)
You may also notice the view zooms out as your speed increases, so you have a much wider view
The stars in the background are awesome! I think it's a little hard to see your projectiles though against the background, maybe make them a little thicker?
Yes, it's a bit hard to see but I haven't really spent any time tuning it - been too busy. Did you nitice the little blue ships that you can shoot to get a token to upgrade your guns? There's red ships that follow you that show up every 30 seconds, and blue ones that contain powerups that show up after (I think) 10k points.
Real time (and spacebar) killer! Got to 257000 points before making myself stop. A few gameplay adjustments and multiplayer, and I bet I'd lose a whole evening to it.
The code appears to be very well-structured and readable, even though it's compiled to JavaScript. IMO, a good example for those learning to use canvas (like myself). Thanks a lot for sharing.
It seems that what you actually want is for CoffeeScript to have configurable backends. I agree that it's silly to generate IE6 compatible code when I know that I'm targeting node. This isn't a reason not to use CoffeeScript -- it's a reason to improve CoffeeScript.
Furthermore, as others have noted, your post does smack of premature optimization. Without numbers, most of the claims are all pretty meaningless. Judging by number of instructions is no longer a valid metric on any platform on any level of abstraction and hasn't been since the 1980s.
I like CoffeeScript and will continue to use it where appropriate.
But I do wonder why we're stuck with all the cruft to let ECMAScript be backwards compatible. Couldn't we just one time introduce a few breaking changes to clean up the mistakes in the language's design?
And if you're really opposed to that, how about the same strict versus transitional semantics we use for HTML? I'd be happy to be writing code in a clean strict subset of JavaScript.
The great thing about there being so many Javascript transpilers these days is that you can pick the right language to suit your needs.
Really want / need Google Closure / the latest ECMAScript stuff? ClojureScript supports these things pretty well.
Really like Ruby (or Python) but find yourself in Javascript land? Coffeescript is right for you.
There's some interesting buzz around getting Coffescript more Google Closure compliant, which is probably the better way to go (assuming your targeting front end JS, not Node).
But yes, there are certainly places where Coffeescript generates a crap-ton of code, where if you can pinpoint your Javascript runtime (like in Node's case) you could do more, better, and faster.
The only thing that's true is that CofeeScript generates some throwaway code because of implicit returns and the "everything is an expression" rule. However, I doubt that they would cause much overhead, specially with modern JS engines optimisation capabilities.
[1]: http://mrale.ph/blog/2011/11/05/the-trap-of-the-performance-...
[2]: http://jsperf.com/don-t-use-coffeescript