11 ms·
Show HN: Fast.js – faster reimplementations of native JavaScript functions
- aikah 12y agoSome V8 people here ? how can a JS re-implementation be faster than the native implementation of a function ?
- GvS 12y agoIt's explained on linked page under 'How?' section.
- ajanuary 12y agoFrom TFA: native functions often have to cover complicated edge cases from the ECMAScript specification [...] By optimising for the 99% use case, fast.js methods can be up to 5x faster than their native equivalents.
- fyolnish 12y agoBy being naive implementations that don't follow the ECMAScript standard.
- netcraft 12y agoThis is mentioned in the readme: https://github.com/codemix/fast.js#how https://github.com/codemix/fast.js#how The two functions do not necessarily work the same way - the native implementation handles edge cases that the fast version drops.
- phpnode 12y agoauthor of the library here. The native implementations have to follow the spec exactly, which means that they have to guard against specific edge cases. The reimplementations in fast.js do not follow the spec exactly, they optimise for 99.9% of use cases and totally ignore the 0.1%. This, combined with the fact that the JS is JITed straight into machine code anyway gives fast.js a significant advantage - it does less work and so is faster.
- sp332 12y agoDo you have documentation on the differences in behavior?
- chrisseaton 12y agoThey're non compliant - it's a meaningless comparison as the two implementations do different things.
- basicallydan 12y agoIt's not meaningless, they're just demonstrating how using the library may be more efficient in "99%" of cases. It's not mean to be a competition :)
- nixarn 12y agoWhy would it be meaningless? The comparison shows that fast.js works for what it was intended to do, it's doing stuff faster than it's native counterparts.
- dspillett 12y agoTo say the comparison is meaningless is a little unfair. Generally yes, the results are not expected to be 100% equivalent as these routines do not produce the same results for some inputs. But as the range of inputs for which the results are expected to be the same is defined, the comparison is meaningful within those bounds (which covers quite a lot of the cases those functions will be thrown at).
- coldtea 12y agoNothing "meaningless" about it. It's not like they do apples and oranges. They do slightly different varieties of apples -- ignore some BS edge cases that few ever use in the real world. If I rewrite project X into X v2 and throw away 2-3 seldom used features in the process, it doesn't mean that comparing v1 and v2 is meaningless. You compare for what people actually use it for -- the main use cases. Not for everything nobody cares about.
- coldnebo 12y agoFrom a computer science perspective it is formally 'meaningless' because the performance improvement was made by changing the requirements, not by a novel algorithm or data structure. This is always possible, but it ignores the original constraints of the problem and hence doesn't shed any additional meaning on how to solve the original problem. From a programmer perspective, that might not change the fact that it's useful. It has 'meaning' to the programmer in that it helps us solve a particular problem. Typically, app programmers are not as concerned with how the problem was solved. I like the library, but to avoid this kind of criticism, don't call it a reimplementation. Call it what it is, an alternative library of functions.
- oneeyedpigeon 12y agoWhich makes it more a 're-imagining' than a re-implementation, but still useful in the vast majority of cases, of course.
- coldtea 12y ago>Some V8 people here ? how can a JS re-implementation be faster than the native implementation of a function ? They say some in their readme. Because the native versions have some extra baggage (sparse array checks, etc). But to answer in general: 1) JS functions also get compiled to native code for often used code paths. That's what the JIT does after all. 2) A JS function might use a better algorithm compared to a native function. 3) Native is not some magic spell that is always speedier than non-native. Native code can also be slow if it carries too much baggage.
- kosinus 12y ago'Native' in V8 also does not always mean 'implemented in C++'. The readme mentions `Array#forEach`. This is the V8 implementation: https://code.google.com/p/v8/source/browse/trunk/src/array.js?r=21951#1147 https://code.google.com/p/v8/source/browse/trunk/src/array.j...
- netcraft 12y agoI wonder how these compare to the ones in lodash.
- spyder 12y ago... and to lazy.js : http://danieltao.com/lazy.js/ http://danieltao.com/lazy.js/
- netcraft 12y agoThanks, I hadn't come across this one before. Looks like they are expecting some API changes in the future though so I'll just bookmark this one for now.
- platz 12y agoor to scoreunder: https://github.com/loop-recur/scoreunder https://github.com/loop-recur/scoreunder
- turbohz 12y agoNever heard of it, but seems very similar to Bacon.js (http://baconjs.github.io http://baconjs.github.io)
- recursive 12y agoWow, very cool. It seems to be linq for javascript, moreso than libraries that actually advertise themselves as linq for javascript.
- jrajav 12y agoGotcha covered: https://news.ycombinator.com/item?id=7938062 https://news.ycombinator.com/item?id=7938062
- idbehold 12y agoCan you provide benchmarks against Lo-Dash?
- cordite 12y agoI'm interested in what those edge cases are, to say it works in 99% of the cases but provide no caveats makes me think that I might be surprised by something if I use it.
- phpnode 12y agoAs well as the example of "sparse arrays" shown in the README, there are some additional slight gotchas around `.bind()`, e.g. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Bound_functions_used_as_constructors https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... These fall outside of the common uses of these methods, and most people don't even know they exist.
- VeejayRampay 12y agoJavascript. The language where you can reimplement basic functions such as map, each, reduce (which by the way are still available for objects in 2014) and have them be faster than their native counterparts. It might be that I don't particularly like the language. but it's kind of frightening that we're building the world on that stuff.
- phpnode 12y agoAn alternative interpretation might be - JavaScript, the high level language language that's so awesome that it can out perform native code* * as long as you make it do less work
- VeejayRampay 12y agoWhy isn't the native version doing less work? Isn't that what you expect from a language design, that the native version will be as close to optimal as possible in the first place?
- kristiandupont 12y agoDid you read the article? These functions are not 100% equivalent.
- VeejayRampay 12y agoFair enough. Why doesn't the title of the post say so then? "Faster incomplete versions of Javascript native functions" would have been a better summary. Or even discuss the fact that if this library is good enough for people to use then maybe the edge cases that the native versions are covering might not be so useful after all?
- jdc0589 12y agoThe native versions have to/should 100% support the language spec and historical behavior. In this instance, it means they can't optimize much that iterates over a sparse array.
- cristiantincu 12y ago> In fact, native functions often have to cover complicated edge cases from the ECMAScript specification, which put them at a performance disadvantage. What. Is. This. I don’t even.
- sp332 12y agoSo if you simplify the implementation, it gets faster but more fragile. Why is that confusing?
- pestaa 12y agoIf you simplify the specification, a proper implementation gets faster with no downside. Why can't we build software on simpler platforms with better implementations?
- sp332 12y agoDoing something complex on a simple platform requires complex code. https://en.wikipedia.org/wiki/Turing_tarpit https://en.wikipedia.org/wiki/Turing_tarpit Having a more complex platform can make things a lot easier for the programmer.
- pestaa 12y agoSimplicity never meant easy. Doing something complex on a simple platform may as well use simple constructs and benefit from no edge cases. For example, Haskell provides only a handful of constructs but allows the developer to build sophisticated systems. Though I agree complex platforms are not necessarily complicated.
- ulisesrmzroche 12y agoYou programmed before? Implementations dont get simpler just because you wish them to.
- pestaa 12y ago
- deleted 12y ago[deleted]
- nathanb 12y agoI'm a bit concerned about this... On one hand, I'm a big proponent of "know your tools". I'll gladly use a fast sort function that falls apart when sorting arrays near UINT32_MAX size if I'm aware of that caveat ahead of time and I use it only in domains where the size of the array is logically limited to something much less than that, for example. But on the other hand, I write operating system code in C. I need to know that the library functions I call are going to protect me against edge cases so I don't inadvertently introduce security holes or attack vectors. If I know that some JS I'm interacting with is using fast.js, maybe there will be some input I can craft in order to force the system into a 1% edge case. The lesson here is probably "don't use this for your shopping cart", but we need to be careful deriding Javascript's builtins for being slow when really they're just being safe.
- VMG 12y agoAt least a list of the corners that are cut here would be nice.
- Isofarro 12y agoAnd a solid suite of unit tests. The current set looks very light.
- phpnode 12y agoThis is actually unlikely to be a problem. The edge cases ignored here are actually the same as those ignored by underscore.js, which is obviously a very popular library.
- cwmma 12y agolodash is the fast one that pioneered this, underscore for the longest time fell back to slow native ones.
- nathanb 12y agoI agree that it's unlikely to be a problem...until your site gets popular and a .01% corner case becomes a weekly occurrence or until someone sees that you're using fast and exploits an attack vector.
- CountHackulus 12y agoNo mention of relative memory usage though. I've been bitten by this kind of thing too many times in node in the past to not wonder about it here. Especially for such core functions.
- illumen 12y agoI did this with CPython and psyco. It turns out that writing map() in python was faster than the builtin C version. Because the JIT was allowed to do some tricks, like inlining the function.
- grhmc 12y agoAmazing, the "performance tests" here operate on a list of only ten items long: https://github.com/codemix/fast.js/blob/master/bench/for-each.js https://github.com/codemix/fast.js/blob/master/bench/for-eac... I'm sure that is a statistically valid way to measure performance.
- sheetjs 12y agoPremature optimization is the root of all evil -- Knuth V8 has excellent profiling tools (exposed in chrome and in nodejs) which should be used first before considering fallbacks. Before seeking a third party library, be sure to check if the function is called many times or is taking a long time. For example, I found that throwing map out and using a straight array (avoiding the function calls entirely) can be up to 50% faster than using the functional suspects. But that, in the eyes of some people, unnecessarily adds complexity to the code and may not be worth changing
- xahrepap 12y agoI think it's a bit unfair to label using a known fast library over a known slow library as "premature optimization". I would much rather start a project or feature with the coding standard of, "use the fast ones", rather than have to go back through all the code, profile it, and replace only the ones hurting performance.
- thathonkey 12y agoYeah but it could be a premature optimization if you blindly decided to use a library because the cost of having to download it (in the case of browser JS) and/or parse (in the case of server JS) an extra script file may outweigh its performance benefits.
- nawitus 12y agoIn addition fast.js functions are not functionally identical to the native functions, just close enough for typical usage.
- sheetjs 12y ago> start a project or feature with the coding standard of, "use the fast ones" Ironically, that involves certain habit changes that completely obviate the library: 1) avoid map. Just create an array and write a for loop directly at the callsite, putting the code in a block rather than as a separate function 2) avoid indexOf. For single-character indexOf, it's much faster and much more efficient to match the character code (loop and check charCodeAt) than to use the function form 3) avoid lastIndexOf. Same as indexOf, except you loop in the opposite direction. 4) avoid forEach. Learn to love the for loop. 5) avoid reduce. See forEach Anyone embracing fast.js is sacrificing some performance to begin with.
- throwaway_yy2Di 12y agoI think in most cases where you'd worry about JS array performance you should use actual numeric arrays [0] rather than the kitchen sink Array(). Also, I think those function abstractions have a pretty significant overhead? [0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays https://developer.mozilla.org/en-US/docs/Web/JavaScript/Type... (edit): Yeah, the abstraction overhead is ridiculous. Here's the forEach() benchmark again, compared to an explicit for loop (no function calls): // new benchmark in bench/for-each.js exports['explicit iteration'] = function() { acc = 0; for (var j=0; j<input.length; ++j) { acc += input[j]; } } Native .forEach() vs fast.forEach() vs explicit iteration ✓ Array::forEach() x 2,101,860 ops/sec ±1.50% (79 runs sampled) ✓ fast.forEach() x 5,433,935 ops/sec ±1.12% (90 runs sampled) ✓ explicit iteration x 28,714,606 ops/sec ±1.44% (87 runs sampled) Winner is: explicit iteration (1266.15% faster) (I ran this on Node "v0.11.14-pre", fresh from github).
- thegeomaster 12y agoI used this in a Firefox OS app, inside an implementation of Dijkstra's algorithm and an accompanying binary heap, and while I haven't run any rigorous benchmarks, I can say the runtime felt way better on my test phone when I rewrote the algorithm to use the typed arrays. This is very often overlooked but extremely useful for implementations of fast algorithms in JavaScript that should scale to a lot of input data.
- deleted 12y ago[deleted]
- phpnode 12y agoregarding your edit, you're exactly right, of course a for loop will be faster. Sometimes you really do need a function call though, in which case fast forEach and map implementations become more useful. The next step for fast.js are some sweet.js macros which will make writing for loops a bit nicer, because it's pretty painful to write this every time you want to iterate over an object: var keys = Object.keys(obj), length = keys.length, key, i; for (i = 0; i < length; i++) { key = keys[i]; // ... } I'd rather write: every key of obj { // ... } and have that expanded at compile time. Additionally there are some cases where you must use inline for loops (such as when slicing arguments objects, see https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments https://github.com/petkaantonov/bluebird/wiki/Optimization-k...) and a function call is not possible. These can also be addressed with sweet.js macros.
- dgreensp 12y agoIt's fairly well-known that Array#forEach is up to an order of magnitude slower than a for-loop, across browsers. The usual reason given is the overhead of invoking a closure from the VM. A JS implementation of forEach ought to be somewhere in the middle. The speed-up for "concat" is surprising to me. I wonder if it holds for "splice" and if that is true across browsers.
- nijiko 12y agoAnd it can be made even faster ;) http://jsperf.com/fast-iter http://jsperf.com/fast-iter
- simonsarris 12y agoHere's another one for you, one of my favorites that used to be drastic: http://jsperf.com/pipetrunc http://jsperf.com/pipetrunc blah | 0; // fast! Math.floor(blah); // slow(er)! (except on FF nightly) Caveat: Only works with numbers greater than -2147483649 and less than 2147483648.
- sheetjs 12y agoAnother caveat: for negative numbers, the bit-or rounds to zero while the floor rounds to negative infinity: > -0.5 -0.5 > (-0.5)|0 0 > Math.floor(-0.5) -1
- al2o3cr 12y agoA fine example why this sort of "who needs the specs, FULL SPEED AHEAD" hyper-optimization can get people into trouble.
- mraleph 12y agoCaveat: if you see numbers in the range of 1,500,000,000 that means your code was thrown away by the optimizing compiler. Microbenchmarks like that require a lot of care to measure something correctly. Check out my talk from LXJS2013 for more details: slides http://mrale.ph/talks/lxjs2013/ http://mrale.ph/talks/lxjs2013/ and video https://www.youtube.com/watch?v=65-RbBwZQdU https://www.youtube.com/watch?v=65-RbBwZQdU
- MokiD 12y agoA while back I was programming for a naive but well-written JS interpreter for set top box apps, where map was generally being avoided because of performance. I wrote quite a fast "map" (along with the others) that looked a bit like: exports.map = function fastMap (subject, fn, thisContext) { var i = subject.length, result = new Array(i); if (thisContext) { while (i--) { result[i] = fn.call(thisContext, subject[i], i, subject); } } else { while (i--) { result[i] = fn(subject[i], i, subject); } } return result; }; I'm not sure if I just used "result = []", but on modern browsers I think that'd be recommended. But yeah, if you're programming for a web browser then using another impl of map is probably going to be a waste of time.
- dabernathy89 12y ago> there is essentially no performance difference between native functions and their JavaScript equivalents > native functions often have to cover complicated edge cases from the ECMAScript specification, which put them at a performance disadvantage. Aren't these opposing statements?
- phpnode 12y agono, but I could probably have worded it better. What I mean to say is that if you do this in JS: function add (a, b) { return a + b; } and this in C: int add(int a,int b) { return a + b; } you're going to get essentially the same performance. The latter sentence you quoted refers to the specific builtin functions that fast.js re-implements. So we first get close to native performance in JS, then we beat the builtin functions by doing less work overall.
- dabernathy89 12y agogotcha, thanks for the clarification
- jrajav 12y agoHere's a jsperf of fast.js / lodash / native: http://jsperf.com/fast-vs-lodash http://jsperf.com/fast-vs-lodash
- phpnode 12y agothanks for this! it looks like there's some room for improvement in the .map / .forEach implementations but the rest seems to stack up pretty well.
- bzbarsky 12y agoThe native bind in Firefox is much faster than the fast.js one (not surprising, since it has explicit JIT support).
- megawac 12y agoFixed the rawgit link to use the rawgit cdn http://jsperf.com/fast-vs-lodash/3 http://jsperf.com/fast-vs-lodash/3
- bzbarsky 12y agoThanks for that. So looking at this in Firefox, the "fast" version underperforms the native one for forEach, bind, map, reduce, and concat. It outperforms native for indexOf/lastIndexOf. In Chrome the "fast" version does better than the native one for indexOf, lastIndexOf, forEach, map, and reduce. It does worse on bind and concat. It's interesting to compare the actual numbers across the browsers too. In Firefox, the numbers I see for forEach are: "fast": 47,688 native: 123,187 and the Chrome ones are: "fast": 71,070 native: 20,112 Similarly, for map in Firefox I see: "fast": 17,532 native: 62,268 and in Chrome: "fast": 38,286 native: 19,521 Interestingly, these two methods are actually implemented in self-hosted JS in both SpiderMonkey and V8, last I checked, so this is really comparing the performance of three different JS implementations.
- garthk 12y agoThanks for that. I can tell the young pups to calm down.
- 12y ago
- Kiro 12y agoSo the forEach magic that is so much faster is... a normal for loop: exports.forEach = function fastForEach (subject, fn, thisContext) { var length = subject.length, i; for (i = 0; i < length; i++) { fn.call(thisContext, subject[i], i, subject); } }; I knew that forEach was slower than a normal for loop but I was expecting something more.
- deleted 12y ago[deleted]
- danabramov 12y agoReminds me of this comment by Petka Antonov on native V8 Promises being way slower than Bluebird[1]: >I'd expect native browser methods to be an order of magnitude faster. Built-ins need to adhere to ridiculous semantic complexity which only gets worse as more features get added into the language. The spec is ruthless in that it doesn't leave any case as "undefined behavior" - what happens when you use splice on an array that has an indexed getter that calls Object.observe on the array while the splice is looping? If you implemented your own splice, then you probably wouldn't even think of supporting holed arrays, observable arrays, arrays with funky setters/getters and so on. Your splice would not behave well in these cases but that's ok because you can just document that. Additionally, since you pretty much never need the return value of splice, you can just not return anything instead of allocating a wasted array every time (you could also make this controllable from a parameter if needed). Already with the above, you could probably reach the perf of "native splice" without even considering the fact that user code is actually optimized and compiled into native code. And when you consider that, you are way past any "native" except when it comes to special snowflakes like charCodeAt, the math functions and such. Thirdly, built-ins are not magic that avoid doing any work, they are normal code implemented by humans. This is biggest reason for the perf difference specifically in the promise case - bluebird is extremely carefully optimized and tuned to V8 optimizing compiler expectations whereas the V8 promise implementation[2] is looking like it's directly translated from the spec pseudo-code, as in there is no optimization effort at all. [1]: https://github.com/angular/angular.js/issues/6697#issuecomment-42771111 https://github.com/angular/angular.js/issues/6697#issuecomme... [2]: https://github.com/v8/v8/blob/master/src/promise.js https://github.com/v8/v8/blob/master/src/promise.js
- sheetjs 12y agoHis "optimization killers" article is also really insightful: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers https://github.com/petkaantonov/bluebird/wiki/Optimization-k...
- JoshTriplett 12y ago> Additionally, since you pretty much never need the return value of splice, you can just not return anything instead of allocating a wasted array every time That kind of optimization seems easily done with a builtin as well: have an option to return the array, and only do so if the JavaScript engine indicates that the calling code actually uses the return value.
- franze 12y agomicro-benchmarks are the root of all evil http://www.youtube.com/watch?v=65-RbBwZQdU http://www.youtube.com/watch?v=65-RbBwZQdU Vyacheslav Egorov - LXJS 2013 talk i don't know if he actually said these word, but it was the overall theme of this (very entertaining and very enlightening) talk.
- webXL 12y agoLooks like John-David Dalton has some work cut out for him!
- grumblestumble 12y agoFrom what I remember, a primary reason Lodash was created as a fork of underscore was to address the "solution" that fastjs provides - underscore had problems with edge cases like sparse arrays, so lodash was created as a spec-compliant alternative. http://stackoverflow.com/a/13898916/1869609 http://stackoverflow.com/a/13898916/1869609
- garthk 12y agoOnly in marketing buzz, and only if he cares. lodash is as fast as fast: see the JSPerf results posted elsewhere. John manages lodash well. He has managed it well for quite a while. Why switch to another library with no track record for little or no gain?
- gpvos 12y agoIt would have been nice though if they would have documented exactly which edge cases they're neglecting.
- peterkelly 12y agoI think the forEach issue is a bad example, and something that could (and arguably should) be handled by the native implementation. The reason they get faster execution here is by breaking the spec. A native implementation could have a single flag associated with the array recording whether it is sparse, and use the more efficient code path given here in the common space where it's non-sparse.
- phpnode 12y agosparse arrays are just one edge case that the native implementation must consider, see this comment - https://github.com/angular/angular.js/issues/6697#issuecomment-42771111 https://github.com/angular/angular.js/issues/6697#issuecomme...
- scott_s 12y agoThe point I took away from that one example was: The native functions have to deal with lots of edge cases, which causes them to be slower. By implementing similar functions which, per their spec, do not handle those edge cases, we can gain a significant performance improvement.
- talles 12y agoI wonder which projects does actually need that. Hey I'm not bashing here, I thing it's kind cool for learning purposes attempts to do such thing, but I truly wonder if there is an actual production need for such thing.
- nijiko 12y agoGame engines, anything that needs to do cycles at a high rate (rendering, algorithms, etc)
- olliej 12y agoAs a person who works on a JS engine I can say that a lot of the speed up in this library is the failure to handle holes correctly - it's surprisingly expensive to do a hole check, although there's still room in most engines to optimise it, those checks are fairly time consuming :-/
- mmastrac 12y agoThis seems like a potential win for JS performance in real-world applications -- an optimization hint to indicate whether an array is "overwhelmingly full of holes" or something less sparse where more optimized versions of the functions can be used.
- gsnedders 12y agoBut then you need to check if you need to alter the flag that says whether the array is full of holes, which is itself an extra cost. It's hard to know what's an overall win, adding cost to save it elsewhere.
- mraleph 12y agoYou can version manually or automatically in the optimizing compiler inner loops of those builtins depending on the denseness / representation of the array backing store. Something along this lines: http://gist.io/7050013 http://gist.io/7050013. Trace compiler could actually give such versioning for free automatically. So I always putting this into not-done-yet category for JS VM related work and it is a very interesting problem to tackle.
- nijiko 12y agoSubmitted a pull-request that does decrementing iterations which in some browsers / engines can give an increase in performance due to less instruction.
- Joeri 12y agoToday i was refactoring some js code that rendered a graph to svg. It was taking several seconds in some cases, and the developer had done a bunch of micro-optimizations, inlining functions, building caches to avoid nested loops, and so on. I ran a profile. The code ran for 2.5 seconds, 4 ms of which in the micro-optimized js code, the rest updating the dom, five times all over again. Needless to say that i threw out all the micro-optimizations, halving the number of lines, and fixed it so the dom was updated once. Anyway, the point i'm making is this: you should micro-optimize for readability and robustness, not performance, unless profiling shows it's worth it. I haven't known a case where pure (non-dom, non-xhr) js code needed micro-optimization for performance in half a decade.
- throwaway_yy2Di 12y agoAn ignorant question -- why do people prefer to render graphics to SVG/DOM, when that's such a noticeable performance bottleneck?
- felxh 12y agoI can't speak for others, but if you write browser apps/websites for a generic audience you basically have no choice. The reason consist of two letters: IE
- throwaway_yy2Di 12y agoBut IE didn't support SVG either until recently? If I read right, it was supported since the same version as HTML5 canvas (IE 9), http://caniuse.com/#cats=SVG http://caniuse.com/#cats=SVG http://caniuse.com/canvas http://caniuse.com/canvas
- timmclean 12y agoTools like http://raphaeljs.com/ http://raphaeljs.com/ allow you to support older versions of IE.
- seanewest 12y agoI think this shows that standards bodies could implement less native language functionality and let community-made libraries/tools compete for those areas. ES6 goes so far as to implement a native module system, seriously calling into question any effort by the community at large to implement a competing system (e.g. browserify, requirejs).
- syg 12y agoThe slowness of functional methods like .map and .forEach for a time was due to their not being self-hosted. Since then, both V8 and SpiderMonkey self-host them, and bz has posted some numbers below [1]. But perf problems are more numerous still for these functional methods, because compilers in general have trouble inlining closures, especially for very polymorphic callsites like calls to the callback passed in via .map or .forEach. For an account of what's going on in SpiderMonkey, I wrote an explanation about a year ago [2]. Unfortunately, the problems still persist today. [1] https://news.ycombinator.com/item?id=7938101 https://news.ycombinator.com/item?id=7938101 [2] http://rfrn.org/~shu/2013/03/20/two-reasons-functional-style-is-slow-in-spidermonkey.html http://rfrn.org/~shu/2013/03/20/two-reasons-functional-style...
- hexleo 12y agoFirst time I meet fast.js, I think it's running fast. When I read introduction I was wrong, it just write fast... I hope one day js run in phone is really FAST.
- hexleo 12y agoI make a big mistake, next time I will read more carefully.
- golem_de 12y agodid you ever google for fartscroll?