10 ms·
Node.js 14 is over 20x faster than Python3.8 for fib(n)
- helloitsian 6y agoI've seen these types of comparisons, and I understand there a loads of factors playing a part in them. However, it does make me wonder, why has python become to standard for data science? Is it Library support or purely community based?
- JesseMeyer 6y agoMost Python data science offloads the data crunching to Numpy, an optimized array based processing library. This is feasible to reduce interpreter overhead considerably by using array programming: c = a + b #This is valid Python code. Where a and b are two same sized numpy arrays. Numpy typically handles the add in an optimized SIMD function.
- masklinn 6y ago> why has python become to standard for data science? Because it's glue, so its speed doesn't matter overly much. > Is it Library support or purely community based? That's a dichotomy which doesn't really make sense. Python has cultivated and attracted attention from scientific communities from the start: the matrix-sig (a special interest group focusing on array computing packages) was created back in '95 and a number of their suggestions were added as language-level conveniences (that continues to this day, `@` was recently added as the "matrix multiplication" operator).
- prepend 6y agoFor me, I have known Python since the 90s but only started using it as a daily driver a few years ago because there were big Microsoft and C/Java groups within my org and choosing one would alienate the other. So I used Python because it was good enough and non-threatening (and free and tons of libraries and healthy community, etc). I would have chosen javascript if there were as many packages. Also considered R, but hadn’t used it at the time. I think Python is a good example of how being good enough is better than being awesome. And then it builds inertia through use and packages and friend of a friend recommendations.
- ghshephard 6y agoIt's because to a reasonably approximation of "None" - none of the actual data science runs in Python, it's all hyper customized libraries which do run (close to) metal fast once the data has been loaded into the appropriate data structures. Pandas is a shim on top of Numpy, which heavily leverages the Fortran77 BLAS/LAPACK libraries. Python is used at the top of the stack because it's an easy language to learn, you can get started fast, and, for places where performance is important - nothing is running in Python anyways.
- masklinn 6y ago> Python is used at the top of the stack because it's an easy language to learn, you can get started fast, and, for places where performance is important - nothing is running in Python anyways. Also interactivity and quick feedback cycle, stuff like Jupyter Notebooks (né IPython Notebooks, a spinoff from the IPython project), matplotlib, ...
- jhgg 6y agoAn interpreter with a JIT is obviously faster than one without. Especially when dealing with CPU bound work. I'm not sure this is entirely noteworthy unless you somehow think CPython has a JIT. Would be much more interesting to compare to pypy.
- masklinn 6y agoIndeed. Furthermore this basically just benches function call overhead by using the worst possible implementation of fib(). Function call is a well-known weak point of cpython, even amongst all its other weak points performance-wise. It's hard to express how utterly uninteresting and useless TFA is, and if its author is surprised by the result… really the only component this tells us about is the author. > Would be much more interesting to compare to pypy. I'm not sure it is more interesting at all, let alone much more, but here are the results on my (obviously much slower than TFA's) machine: > python3.9 --version Python 3.9.1 > python3.9 fib.py 8555.904865264893 ms > pypy37 --version Python 3.7.9 (7e6e2bb30ac5fbdbd443619cae28c51d5c162a02, Jan 15 2021, 06:03:20) [PyPy 7.3.3-beta0 with GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] > pypy37 fib.py 715.0719165802002 ms > node --version v14.15.4 > node fib.js 247.19056797027588 ms (can I note that the 12 decimal precision of the script is hilarious? Because clearly when you're benching fib(35) you need that femtosecond-scale precision)
- zamadatix 6y agoSeems like an unduly harsh take. Is everyone just supposed to inherently know this fact about cpython or find it unsurprising when they run across it? "Obviously this isn't the most comprehensive benchmark, but the results are surprising to me." I fully agree with this and I learned something new about cpython's weakpoints today!
- dooferlad 6y agoOh, I think it is a quite reasonable comment. It isn't interesting work being done in the benchmark and the benchmark itself is short. If you want to get ultimate performance from Python then write a C function... If you want to inform me about runtime performance then show me how the language runtimes are spending cycles. If you wish to convince me about a language being great then tell me about the engineering effort to create and then run something in production.
- mStreamTeam 6y agoI'm honestly not too surprised. I follow the v8 blog and they talk extensively about performance improvements on most releases.
- k__ 6y agoV8 is a monster. If you can trust language benchmarks, you only get notable performance benefits when switching from JS to Rust/C/C++.
- richardwhiuk 6y agoThis is a pretty terrible implementation of fib(n).
- meetups323 6y agoIt's a common approach to measuring function spawn cost.
- da_chicken 6y agoMaybe, but it's also why synthetic benchmarks are not convincing. Maybe node better handles a bad pattern, but if performance is a concern to this level we're more concerned about functionally equivalent good patterns even if the code is very different.
- atleta 6y agoI think GP meant how the fib function was written (and not why it was chosen for the measurement). The `if n == 1 or n == 0` thing hurts my eyes too.
- nullcat 6y agoRegardless node IS definitively one of the fastest interpreted platforms around. It is well known that it is faster than python. Python wins in other areas, including being a much much better designed language.
- tracker1 6y agoProbably comes from V8 (JS engine in node), likely being the most heavily optimized language runtime engine ever made.
- locotower 6y agoYeah, it's definitely because of that.
- killsgnadfamily 6y ago
- SuchAnonMuchWow 6y agoDoesn't the Node.js version use double precision floating point vs python using infinite precision integers ? That would explain part of the difference in performance, and make the python version exact, but js version inexact.
- nullcat 6y agoThat's one factor but there is an overall reason behind performance difference. The main reason is v8 and the inordinate amount of resources google has thrown against that thing to make it ultra fast. You should read up on the people who work on it.
- d0mine 6y agoThe numbers are small so there shouldn’t be any difference for fib(35)
- meetups323 6y agoThis is correct, though both are exact at the scales in question (14930352). There's a more general question of whether it's beneficial to take a perf hit for all arithmetic in order to support some corner cases of infinite precision, or be explicit that standard arithmetic won't be precise, but you can opt into it via some mechanism (BigNum, in the JS case) I prefer the JS approach.
- wongarsu 6y agoThe specifications do say that JavaScript only has floating point numbers (and no integers) and that Python has infinite precision integers. But in implementation, for whole numbers small enough to fit into a regular 32-bit integer both Python and Node.js use regular integers as an optimization. fib(35) comfortably fits that. I guess node.js might have the edge here with the necessary overflow checks in the addition. Both languages have to do them to fall back to either doubles or bigints respectively, but Node.js's JIT can probably do them faster.
- fermigier 6y agoFYI: pypy3 is 10x faster than CPython on this benchmark. ~> python fib.py 4825.7598876953125 ms ~> pypy3 fib.py 514.7459506988525 ms
- fermigier 6y agoAlso, add a couple of type annotations to the program: import time def fib(n: int) -> int: if n == 1 or n == 0: return 1 return fib(n - 1) + fib(n - 2) t0 = time.time() fib(35) t1 = time.time() print(f"{(t1 - t0) \* 1000} ms") The run: ~> mypyc fib.py And boom: ~> python >>> import fib 332.64994621276855 ms (FYI, mypyc is a compiler that's part of the mypy package).
- Florin_Andrei 6y agothere's a backslash in the print statement that crashes it
- masklinn 6y agoWouldn't just straight running this through cython make more sense? Or numba?
- singhrac 6y agoWell, a point in mypyc’s favor is that the above code is still syntactically valid Python code.
- masklinn 6y agoBoth numba and cpython work with python code AFAIK. I don't know that cpython would take advantage of mypy annotations and you can make a cpython program not python-compatible, but you don't have to.
- williamstein 6y agoHere are some timings using three different approaches using Cython, and also numba: https://share.cocalc.com/share/df81e09e5b8f16f28b3a2e818dcdd4560e7818ae/support/2021-02-09-fib-cython.sagews?viewer=share https://share.cocalc.com/share/df81e09e5b8f16f28b3a2e818dcdd... Numba wins and is about twice as fast as my most clever Cython code. Naive Cython is pretty bad, but more clever Cython is reasonably good (though not as good as numba).
- tuckerconnelly 6y agoPython feels noticeably slower than Node.js, particularly when running scripts with large amounts of imports. I now pretty much always use JavaScript for, well, scripting. Not sure why Python and Ruby are considered go-tos there.
- nullcat 6y agoPython as an implementation is slow but python as a language is much better designed then javascript. That is the main reason why they are gotos.
- offtop5 6y agoEh, when it comes to scripting, performance is almost never a concern. Different tools are best for different jobs, for example if you need to run some basic NLP jobs pythons going to be much better.
- wongarsu 6y agoPython gives you better escape hatches for typical compute-heavy work (lots of libraries use C under the hood), and Python has a better multi-threading story than Node.js. But I guess the biggest differentiators are really the ecosystems and standard libraries. Node.js is certainly catching up, but Python has generally a better selection of high-quality libraries for tasks beyond the web.
- brrrrrm 6y agoI believe libraries like v8pp are helping to shrink the gap with C library integration.
- tuckerconnelly 6y agoLack of library support is probably the most valid reason here. Most of the other reasons people have posted seem like opinions on ergonomics. I think those held true 10 years ago, but modern JavaScript feels very minimal and lisp-y and is more enjoyable to program with than Python IMO. What libraries or escape hatches to you actually use in your daily work that are exclusive to Python? The ones I'm familiar with would probably be OpenCV and the whole machine-learning family of libraries (sci-kit, spacy, tensorflow, etc).
- atraac 6y agoWho would've thought that V8 that gets millions invested in it by a huge company would outperform community made Python.
- carlmr 6y agoI'd be hard pressed to find any mainstream language that underperforms naïve CPython. Community driven or not.
- simple_phrases 6y agoBash is pretty damn slow.
- eatonphil 6y agoNow try the tail recursive version! :)
- deleted 6y ago[deleted]
- cccc4alll 6y agoJavascript runtime is based on efficiently processing callback functions. Not a big surprise on recursive algorithm, which is function call algorithm.
- simple_phrases 6y agoNow optimize it with PyO3 or PyOxidizer.
- CivBase 6y agoIgnoring the bad implementation of fib(n) and use of a Python interpreter without JIT... why does this matter? Python and JavaScript are scripting languages. Their advantages are being highly portable and relatively easy to develop and maintain. Performance has always been a weakness of both languages when compared to their pre-compiled siblings. That limitation is often mitigated by "gluing" together functionality implemented in a more performance-oriented language, but even then nobody chooses a scripting language because they expect it to be faster than the competition. Besides, this is hardly a fair comparison. Many tech giants have competed in the browser space for years by hyper-optimizing their JavaScript engines. Comparing the performance of Node/V8 to that of CPython is like me comparing my strength to that of a child.
- brrrrrm 6y agoI think it's notable that the gap between dominant scripting languages for simple function-call bound code has become quite large.
- CivBase 6y agoI do not consider the difference in performance for that particular implementation of that particular function on those particular interpreters to be notable. I don't think it's a fair match-up and I don't think there's much value in comparing the effectiveness of tools for a job they aren't made for. For additional comparison, I quickly I rewrote the function in C (output and code below). The code was comparable in length and complexity (at least the fib(n) implementation was), but the relative performance is enough to make JavaScript blush. If you really wanted to do something as trivial as this, why would you even use pure JavaScript or Python to begin with? And if performance was a concern, why would you choose a reference interpreter like CPython? Output: $ ./fib 35 14930352 68 ms Code: #include <stdio.h> #include <stdlib.h> #include <sys/time.h> int fib(int n) { if (n == 1 || n == 0) return 1; return fib(n - 1) + fib(n - 2); } int main(int argc, char *argv[]) { if (argc < 2) return 1; int x = atoi(argv[1]); struct timeval start, end; gettimeofday(&start, NULL); int n = fib(x); gettimeofday(&end, NULL); printf("%d\n", n); long unsigned int udiff = ( (end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec); printf("%lu ms\n", udiff / 1000); return 0; }
- loloquwowndueo 6y agoI mean sure, code the thing in assembly and it’ll run circles around node. But who would do that? I’d also take python any day over js which makes my eyes bleed and my face hurt from all the face palming at the ecosystem’s insanity.
- davesque 6y ago1. Python doesn't have a JIT. This shouldn't be surprising or headline worthy. 2. Why benchmark an O(2^n) fibonacci? It's basically benchmarking call frame creation. 3. A single order of magnitude is honestly not that impressive a speedup for JIT vs. no JIT. Might have a lot to do with the inefficiency of the recursive fibonacci func. Also, to quote another poster: @numba.njit def fib(n): if n == 1 or n == 0: return 1 return fib(n - 1) + fib(n - 2) After JIT warms up: ~86 ms Which is...effectively identical to Node?
- masklinn 6y ago> Which is...effectively identical to Node? You'd have to also run the node version on your machine to know, as it's unlikely you have the exact same setup as TFA.
- contravariant 6y agoOf course in the category of 'single line' performance optimizations the most effective one is going to be: @lru_cache(1000) def fib(n): if n == 1 or n == 0: return 1 return fib(n - 1) + fib(n - 2) which lowers the time to somewhere around 20 microseconds. I'd be interested to know if Node.js can do anything similar.
- maxmaio 6y agoI know it's not super relevant to node vs python3, but your fib(n) has a time complexity of O(2^n)... with a dp approach it can be solved in O(n). also your space complexity can be reduced to O(1).
- contravariant 6y agoWith a better chosen dp approach you can even solve it in O(log(n)). Though at that point the extra cost of multiplying large integers becomes non-negligible.
- maxmaio 6y agoI'm having trouble coming up with this approach on my own. could you share it please?
- w3news 6y agoCompare languages on performance is weird. Every language is made with another philosophy. Python isnt made for performance, but for good code readability. Write clear, logical code for small and large-scale projects. It is also made by Guido to build applications in less time. Guido knows his language isnt the fastest, but thas wasnt the goal with Python. Node.js is also made for other applications than Python. It's great for web developers to be in the "JavaScript everywhere" world. So it is easy for web developers to write backend and frontend code with the "same" language. It's also great for event's and "real time" communication with the (web) application.
- colanderman 6y agoSyntactic differences aside, the capabilities of JavaScript and Python do not differ significantly. They are both highly popular highly dynamic object-oriented-ish languages. Knowing that the most prevalent implementation of one is significantly faster than the most prevalent implementation of the other is useful information for someone deciding between the two for a project where performance is important. Comparing alternative implementations of the languages, which are geared toward performance, would also be valuable. But simply knowing that, if your choice to use CPython is more-or-less arbitrary, you're leaving performance on the table, is valuable. (Of course, as discussed in the top-level thread by @SuchAnonMuchWow, this particular benchmark seems to be comparing apples to oranges, and thus may not be of much value.)
- deleted 6y ago[deleted]
- ehutch79 6y agoIsn't time.time() specifically not accurate to that degree and why you should use time.perf_counter_ns()?
- singhkays 6y agoLooks like this is not fully compatible with Apple Silicon M1. I tried to install Pandas along with PyPy and ran into failure on building numpy. Looks like it's a known issue https://github.com/numpy/numpy/issues/17807 https://github.com/numpy/numpy/issues/17807