10 ms·
Three JavaScript performance fundamentals that make Bluebird fast
- meeper16 10y agoWhy does that guy look rekt and hungover in the article?
- franze 10y agoAn article about performance on a 2.2 MB [1] page (~40% of this is JS[2]). With a start render event at about 6.6 seconds on 3G Fast / US [3]. The medium is the message. [1] https://tools.pingdom.com/#!/cBcAKw/https://reaktor.com/blog/javascript-performance-fundamentals-make-bluebird-fast/ https://tools.pingdom.com/#!/cBcAKw/https://reaktor.com/blog... [2] https://www.webpagetest.org/result/160905_P8_P45/ https://www.webpagetest.org/result/160905_P8_P45/ [3] https://www.webpagetest.org/result/160905_P8_P45/1/details/#waterfall_view_step1 https://www.webpagetest.org/result/160905_P8_P45/1/details/#...
- Klathmon 10y agoWould you feel the same way about a book on performance optimizations? The medium says nothing about the message. The message isn't even about load time performance, it's about runtime optimizations.
- tuxracer 10y ago> The message isn't even about load time performance, it's about runtime optimizations. There tends to be a fetishization of load time and time to paint performance on web, and gross neglect of run time performance and user experience once the web app loads. Some devs seem to forget someone is going to want to actually interact with this thing once it loads and 5fps needlessly jittery, janky UI (among other things) has contributed to the death of mobile web altogether in favor of native apps.
- underwater 10y agoHand optimizing hot code paths is a completely different challenge than minimizing JS overhead for a web page. Your complaint has very little to do with the content of the article. And, even if it did, it wouldn't make the tips in the post any less valid.
- catnaroek 10y agoAren't most of these “optimizations” things that a decent programming language implementation should automatically do for you in 2016? (Lambda lifting, using efficient representations for variant types, etc.) Rolling them by hand is awfully low-level, and completely defeats the point to using a high-level language. --- I can't properly reply to your replies, because “I'm submitting too fast”, so I'l reply here. @leppr: I'm not denying the importance of these optimizations. I'm saying that they're being performed by the wrong programmer, or rather, by a programmer performing the wrong role (language user, rather than language implementor). @pizlonator: > Avoiding allocations is generally good advice. Compilers have a hard time eliminating them The most effective way to avoid allocations is to make the language value-oriented (where values are merely represented in physical memory, but not identified with those representations) rather than object-oriented (where the physical identity of every object matters). An implementation of a value-oriented language is free to store the entire representation of an arbitrarily large compound value in a single memory block. By comparison, the gross amount of micromanagement shown in the article is a lot of effort, whose benefits have only limited local significance. > Using bitfields is a classic trick that is harder to do for the implementation than it is for the user. Then provide an abstract bitfield type as a library, and let that type be used by everyone else as if it were a primitive type. > Finally, I love the no-op function trick. This is not a low-level optimization at all! It is. What you really want here is an abstract type of lazy suspensions. Then, again, that type can be used by everyone else, without caring about its internal implementation. @macspoofing Wholeheartedly agree. I have no idea why you're being downvoted.
- macspoofing 10y agoEven if it doesn't, how much time is this actually saving? If you're doing heavy work on every frame ... maybe (and you'll have to profile to figure out if it's worth). If you're handling a user input event, or some IO event (like in the author's example) it makes no difference at all. It'll confuse some developer (possibly a junior or co-op tasked with clearing the bug queue) down the road, and probably will lead to a bug.
- leppr 10y ago>Rolling them by hand is awfully low-level, and completely defeats the point to using a high-level language. The problem is that you can't have "compiler/interpreter plugins" on the web, you have to use the language itself in order to extend it. This isn't React, Angular or even jQuery we're talking about, it's a library implementing a "fundamental" language feature that may be used tens of thousands of times in an app. This is why these kind of extremely low level optimizations matter for the makers of such a low-level library.
- macspoofing 10y agoInteresting article now take these suggestions and toss them out the window. Architecture, correctness, maintainability and readability of code are much more important than optimizing for these extreme edge cases. If there are performance issues, profile and refactor only the affected areas. Most of the time your code isn't going to get exercised enough to make any difference. You're also fighting JIT assumptions, since all VM devs will attempt to optimize against common patterns - so though these performance 'bottlenecks' may be true today, that may not be the case tomorrow. Anectode: I had a co-op student preemptively apologize for using a double for-loop brute force search as non-optimal and not 'clean', during his code-review. The lists in question were guaranteed to have a size of 5, and that code was executed once per life-time of the app.
- tehlike 10y agopremature optimization is the root of all evil.
- mpweiher 10y agoThe actual quote is a bit different: "We should forget about small efficiencies, say about 97% of the time; premature optimization is the root of all evil." It goes on: "Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified." Just before that section: "The conventional wisdom shared by many of today's software engineers calls for ignoring efficiency in the small; but I believe this is simply an overreaction to the abuses they see being practiced by penny- wise-and-pound-foolish programmers, who can't debug or maintain their "optimized" programs. In established engineering disciplines a 12 % improvement, easily obtained, is never considered marginal; and I believ the same viewpoint should prevail in software engineering. Of course I wouldn't bother making such optimizations on a one-shot job, but when it's a question of preparing quality programs, I don't want to restrict myself to tools that deny me such efficiencies" From "Structured Programming with go to statements" Knuth, 1974.
- 10y ago
- tonyle 10y agoHe also has a nice page on his github with lots of info on making stuff fast on node. https://github.com/petkaantonov/bluebird/wiki/Optimization-killers https://github.com/petkaantonov/bluebird/wiki/Optimization-k...
- romanovcode 10y agoI don't get the obsession with benchmarking and making node "faster". If you want your application to be blazing fast why pick relatively slow language like JS in the first place?
- pizlonator 10y agoWow, the function overwriting trick is really great. WebKit is likely to inline the no-op function in the third and fourth optimizing tiers, so if the rare thing does not happen, the no-op hook call is basically free. Cool! I wasn't aware that function object allocation was such a big deal. It's a big deal if the function is used as a constructor, but other than that, function objects are some of the cheapest objects we allocate, at least in WebKit. Also, WebKit's fourth tier will eliminate nested function allocations if all of the calls to those functions are inlined. From helping with that work, I know that the cost of function allocation is small because even in the best case, the speed-ups from this optimization weren't earth-shattering.
- z3t4 10y agou have to measure and pick your battles. Im gonna try the int bool trick later to see if there are any gains.
- Pelam 10y agoI always appreciate when libraries and tools are carefully engineered for performance, provided the abstraction holds and the thing solves the problem it is supposed to. It seems to make sense to invest the most energy in optimizing and otherwise improving the tools that are more general and used widely. In which case this library clearly fits the bill. On the other hand in application code, possibly while still experimenting or developing ideas it makes most sense to aim for maximum readability and simplicity. Optimization can be left for when there is a proven need for it.
- dalbin 10y agoAre there people working on JS Engine ? I would like to have more info on why JS create unnecessary new function objects if there are only called in the parent function scope.
- vickychijwani 10y agoThe author answers this in the comments [1]. > Functions are also first class objects with observable identity, just like any other object. Identity can be observed in many ways, for example by doing an equality comparison or assigning a property. In the first example optimization is indeed possible as it's easy to see that the functions cannot be used for their identity. Optimizations have maintenance costs however and if similar simple scenarios are not common in the real world the optimization might not be worth implementing. [1]: https://reaktor.com/blog/javascript-performance-fundamentals-make-bluebird-fast/#comment-2869461847 https://reaktor.com/blog/javascript-performance-fundamentals...
- qwertyuiop924 10y agoOkay, so we're supposed to avoid function allocations like the plague, and using bitfields to represent sets of data. They 80's called, they want their optimizations back. Using bitfields, in particular, is a heavy sacrifice in clarity for relatively few wins. As for function allocations, internal functions can be hidden by binding the actual function to the return value of a closure that instantiates both the main and internal functions, and returns the main. You can't get rid of the cost of functions in the general case, though: a function's lexical environment has to be recreated each time the function is called (otherwise, all the variables are what C calls "static"), and JS's object semantics mean you can't just make one function, and rebind it to the appropriate parent lexical environment at call time (I have no idea if that's a useable optimization, but it occurs as a way to cut down on allocations) although you could bind the function code to multiple function objects with different parent lexical environments, which would largely accomplish the same thing (but now I'm just thinking out loud). If you really need these optimizations, go ahead, use them, but don't take these tips unreservedly, and use them in your next project.
- userbinator 10y agoUsing bitfields, in particular, is a heavy sacrifice in clarity for relatively few wins. Only to those who don't understand bitfields, which IMHO means they don't even understand the basics of how a computer works, let alone how to effectively program one. JS is a high level language, but it still has bitwise operators for a reason.
- albinofrenchy 10y agoI disagree. Bitfields of somewhat unrelated fields is a sacrifice in clarity even if you understand bitfields perfectly well -- I'd argue anything requiring boilerplate sacrifices something in the way of being able to understand a code base.
- qwertyuiop924 10y agoI disagree. Bitfields mean that you have to do a lot of boilerplate operations which obscure the actual meaning of what you're doing, and can confuse even those who know what's going on, as an error can creep in easily.
- andrewalan 10y agoHello there, are you having issues with your partner ??? Whether trust issues or cheating...worry no more because I can help you spy on them without knowing like cloning their mobile phones,hack into their social networks accounts like Facebook,Instagram,Twitter,We Chat,Whats app etc. I also upgrades school grades,tap into cctv security systems, transfers into accounts worldwide,clear criminal records,help in purchase of hacking tools and software, that's just for a few to mention. You can contact me via mail on ...Andrewalanhacks@gmail.com
- andrewalan 10y agoHello there, are you having issues with your partner ??? Whether trust issues or cheating...worry no more because I can help you spy on them without knowing like cloning their mobile phones,hack into their social networks accounts like Facebook,Instagram,Twitter,We Chat,Whats app etc. I also upgrades school grades,tap into cctv security systems, transfers into accounts worldwide,clear criminal records,help in purchase of hacking tools and software, that's just for a few to mention. You can contact me via mail on ...Andrewalanhacks@gmail.com
- marknadal 10y agoI can attest strongly to these optimizations - and for everybody who is saying "don't worry about it" in these threads you would be surprised at how wrong/bad JS perf is without these. Every function call in JS (even named functions that do not have to be created at execution time) have logarithmic decrease in performance (this means your 2nd function call can half your performance). Using these techniques and others, we've been able to get some unbelievable results (30M to 50M ops/sec) for our JavaScript library. Check out this link for a podcast on how we did it as well as more information: https://github.com/amark/gun/wiki/100000-ops-sec-in-IE6-on-2GB-Atom-CPU https://github.com/amark/gun/wiki/100000-ops-sec-in-IE6-on-2... .
- rastapasta42 10y agoWouldn't bit-shifting to store booleans in 1 bit actually decrease performance, for minimum size improvement?
- mannykannot 10y agoWhen you have caching and also when you have dynamic allocation, size has its costs. Not every time and certainly not linearly, but more likely than the opposite.