Node.js: Some quick optimization advice
medium.com
medium.com
Asking developers to remember the "gotcha" of 600 characters is not really viable. Instead, if this is important to you, consider the addition of minification or comment stripping to your production deployment process. Minification will also make the variable names and syntax use shorter, saving you further precious characters.
Learn the problem, but automate the solution.
What do other developers out there do?
Note the 'benchmark' in OP is run 500 million times to see the performance difference. This is definitely not a common scenario.
If your program is not CPU-bound, or if it doesn't have a function that's called millions of times in a tight loop, or if that doesn't make up the majority of time spent on CPU, or if that function does more than execute a couple of instructions, then the performance difference will likely be enormously less.
This sounds like a horrifying hack but it's also pretty similar to how Angular's shorthand DI works.
> This sounds like a horrifying hack (...) how Angular's shorthand DI works.Love me some FOAM: https://github.com/foam-framework/foam/blob/master/apps/todo....
The success of an endeavor is proportional to the number of shitty hacks that have come before it. Sometimes this it true in a literal sense -- sometimes a project consists of shitty hacks. But the astute reader will notice that a hack is only known to be shitty because someone did it, and had the courage to make their example public.
Do we reward their courage? No. We act like cliquish teenagers and rip them apart.
I don't mean to single you out. But this subthread consists of a developer at Amazon, an unknown, and a founder -- the very types of people I wanted to respect -- yet the content is little more than "Look at how stupid these people are." What kind of example are we setting here?
Be excited about X! Whether X is FOAM, Javascript, COBOL, C++, Python, Erlang, Scheme, NPM, ASDF, Vim, Stallman, or a song. Be happy. Be amused. Be anything but bitter.
In this instance, FOAM shows what's possible. Is it necessarily a good idea? Who cares! We've learned something new! Be excited!
How certain are you that an idea that strikes you as bad is actually bad? For every possible circumstance? What about with a slight tweak? In fact, "An idea that seems bad" is the short definition of "startup."
Most ideas that seem bad are, in fact, bad. But it's important to fully explore the problem space before dismissing them, else you'll dismiss Facebook.
This subthread is about a software technique, not a startup idea. But is it really such a different domain? Would the idea of Python have survived if it had been introduced in the era of Multics? It wasn't a compiled language, so it couldn't hope to survive back then. Yet its time was coming, whether or not it would have been dismissed at the time.
"Under what circumstances could this be a good idea?" That's the valuable question. And if you also have a good answer to "Why now?" then you may be onto something. In fact, you might be one of the first people to notice that an idea has flipped from bad to good. Seems like a pretty powerful position.
It seems like most influential work started as a hack. (TeX is a notable exception.) So if you want to do influential work, be delighted by hacks. It'll make them easier to explore, and you might end up in a position few others realize is valuable.
I shouldn't have said that the code was unpleasant, which is obviously subjective, but I should have said "the code style is quite unusual for JS", which it is. It was certainly not my intention to "trash their work".
If I had to suggest a change, I would use the 600-char count as a starting point for one-time functions, and then count the number of calls to a function, counting how many instructions it produces (basically tossing an incrementing variable into the compilation state, and storing it per Function object).
But then again, I've never played with the inside of V8, only the outside. I consider myself lucky to be in that position, because V8 is pretty dang sweet.
http://wingolog.org/archives/2011/07/05/v8-a-tale-of-two-com...
If a function is hot, then it gets promoted to V8's optimizing compiler, which is currently Crankshaft but will soon be replaced by Turbofan. This compiles the AST first into a high-level IR, Hydrogen, which is an architecture-independent SSA-like form vaguely reminiscent of LLVM. Then that's lowered into an architecture-dependent IR, Lithium, where register allocation and instruction scheduling is performed.
http://jayconrod.com/posts/54/a-tour-of-v8-crankshaft-the-op...
If you read the bug for this that someone posted up-thread, the AST information is fully available when inlining in Hydrogen, but a patch to remove the character limit tanked one of their benchmarks. Also, they didn't preclude fixing it in Turbofan, only in Crankshaft, and that's largely because Crankshaft is on its way out.
(I've played a little with the internals of V8, but am not an official developer. Also, one of my friends is the Bay Area TL for V8.)
If comments aren't completely ignored by the parser, then there has to be some case where a comment inside a function has an observable effect?
Surely this must be undocumented features of the language spec?
(Or rather, that's the first step of deciding. It will inline larger methods if they're sufficiently hot).
What kind of optimization step is prevented here?
Whenever I begin to convince myself that JS and Node are actually fine languages / environments to code on, some weird edge case like this pops up.
Not entirely sure if it's just its popularity, which is bound to expose its rough corners, or if it's fundamentally bad designed (written in 10 days in the late 90's, etc)
Netscape browser has not been used in a long time, and JS has been standardized as ECMAScript since the late 90's.
I could describe almost any language that builds on previous language idioms like this. C++, most of the later Lisps, Java for sure, C# especially, Objective-C certainly... etc.
You're assuming your conclusion then trying to prove it with personal opinion.
We need to revisit the scripting in browsers. Instead of twisting arms to use "JavaScript", because of it "universality", we should focus on WebAssembly and the likes. Have a safe scripting VM in the browser, use any language that compiles to it - no need for Babel and the likes.
No, again, you're reforming "I would like..." into "we should". There's no should about it.
JavaScript is nowadays quite a nice language. ES2015 and the way forward gives us a language that could happily go for another 20 years with few issues.
WebAssembly doesn't solve the problem btw - most of the things people hate on JS about (that aren't just dumb "I don't like loose typing or understand prototypical inheritance" complaints anyhow) are to do with how it integrates with the key web feature: the DOM.
DOM is where everything goes to hell on the web and it's going to be just as much of a mess in C/Rust/Haskell/Clojure/brainfuck as it is in JavaScript.
Also your comment about Babel is just strange. The reason to use Babel is to support older parsers that only understand ES5 syntax. That's never going to go away. We'll be dealing with older parsers for 10 years after WebAssembly launches - so guess what? Now your toolchain got longer, more complex, and you still have to output JavaScript anyhow.
Yaaaaaay.
Or, you know, you could learn JavaScript properly and realize that it's a completely useful and great language that is just as good as whatever your pet favorite is when applied to the tasks at hand.
When it comes to non-browser production code (e.g. servers), it's NodeJS or nothing.
IMO this is what we need:
* a better designed standard library. Maybe more like Dart's[1] - we already have Bluebird as the de-facto replacement for callbacks - all we need now are something like Dart's streams to fix the built in quirky streams.
* built from the ground up with optional types i.e. TypeScript or Flow (eliminates most of JS's type-related quirks while preserving most of the dynamism and duck typing and being very helpful when the time comes to refactor)
Now that typescript has support for type definitions inside node_modules[2] there are no barriers remaining to do this. node + V8 + typescript can provide a development experience that matches Dart (exceeds it in some cases, e.g. REPL) without throwing away the entire existing JS ecosystem in the process.
[1]: https://api.dartlang.org/1.12.1/dart-async/dart-async-librar...
[2]: https://github.com/DefinitelyTyped/tsd/issues/208
p.s. [2] can actually detect some situations in which there would be problems when multiple library versions coexist together (e.g. when you pass instances that come from library v3 to a function of library v2, explained in detail at https://news.ycombinator.com/item?id=8213273). However if the interfaces are structurally satisfied, the compiler will not complain. As a result I'm pretty sure that its possible to write a tool that detects semver violation based on .d.ts files (similar to what Elm does) or suggest the exact amount of version number increment by comparing the definition files
With the latest version, you have block scope, you have a shorthand function syntax, the "this" nonsense is teeny bit less awful, there's help at hand for the inevitable callback chains, and strict mode is still there. There's also a new class syntax (though actually - aside from "this"! - I thought the old-style classes were the least of its problems).
I won't apologise for rolling my eyes a bit at how it's taken until ver 6 to get block scope, but better late than never.
The one possible exception may be Python, but this is because the PEP process requires that you very rigorously lay out interactions with existing language features, and Guido is pretty conservative at accepting them. This means Python evolves slower than many other languages, and the last attempt to fix many of the awkward rough corners (Python 3) led to a multi-year transition that adversely hurt Python's popularity for a long time.
As Bjarne Stroustrop said, "There are two kinds of languages: those that nobody likes, and those that nobody uses."
Historically, I preferred to use inline JsDoc style comments as the source of documentation for my public APIs. Recently though, I decided that I didn't like them and that I wanted something better. I was hoping to find some tool that parses my JS to AST, figures out what was being exported (e.g. what was public) and writes a JSON document that I could diff over time, to figure out what was documented and what wasn't (in my external docs). So far, I have found this project called `doctor` which sounded close to what I'm looking for, but it still relies on comments ~ https://github.com/jdeal/doctor ~ So, I might have to write it myself using something like Esprima to get the AST...
You can of course strip comments when making builds. In fact you can even write functions of more than 600 chars and get away with it as long as you use a minifier. If you have a minified function of more than 600 chars then that's a bulky function which should instead be split in smaller ones.
In frontend JS code sure, but minifying backend node.js code is certainly not "best practice".
Re: this comment, if you just don't make huge comments inside the body, but rather above it - as is the usual standard - this is less of an issue.
Now that we have ES6 imports and wide CommonJS support I don't see any good reason to use hacky DI with Function#toString.
The toString() on a function is very useful in more ways than awful eval hacks. The most useful way is how I use it in msngr.js for creating keys for methods that handle events.
So let's say your custom object has a way to handle events. Surely you want to allow more than one method to be hit for each event, right? So internally to your object you keep track of this by the method's contents as a sort of key or hash that always points to that specific method. Then you can remove handlers by simply passing in a method. No requiring special keys or anything to identify a function as a function is its own key.
Make sense? It's most useful for developers who work on frameworks or objects that require some custom eventing that can be used by multiple places.
If you really want to deprecate this functionality then you need to provide a way to hash to create a unique key based on a function itself. The only other way around it is adding more verboseness to the language or event handler calls which doesn't add anymore clarity.
I think all the dissenters missed that part (about it being "one point" in favor/not in favor). I thought programmers were supposed to be good with subtle details, but it seems like the majority of them lose that ability when talking about religious topics.