Truth can be harsh, but people sometime overvalue to such an extent is hard to understand.
Truth can be harsh, but people sometime overvalue to such an extent is hard to understand.
sum = 0
for i in xrange(n):
for j in xrange(i):
sum += A[i][j]
And when they reach that milestone, some people call it "as fast as C".Never mind that that's not what people actually write in Python or PHP. It's a synthetic benchmark, not a real workload.
The workloads in those languages are generally oriented around strings, hash tables, and function/method calls.
And the JITs don't seem to do nearly as good a job there. I tested PyPy on Oil [1] a few years ago, and it made it slower, not faster. And it used more memory. (Though PyPy is an amazing project in many respects.)
You usually don't care how your matrix multiplication/regex matching/unicode normalization/JSON parsing is implemented, but people had to make those, and they are users of the language too.
Even though it might not change the bottom-line for your high-level app.
Julia is a dynamic language that seems to do better because it was designed for this purpose.
But it doesn't seem to have panned out in practice in Python, or PHP as far as I know. Those languages have huge piles of C, and whenever you call into C, the JIT gets confused. People don't seem to rewrite their huge piles of C in Python or PHP. In Python, it's more likely Cython.
I'd like to see pointers to counterexamples -- where people actually wrote some C-like code in Python or PHP and let the JIT do its work. I haven't seen it, aside from the PyPy project itself, and maybe a few other examples. I think you would still take a significant performance hit.
The issue is that C compilers in 2020 are even better at compiling the example I showed. They do amazing things with that kind of code that state-of-the-art JITs don't in practice.
So if a Python JIT does 10-50x better than CPython on a numeric workload, that sounds impressive, but it's still slow compared to C.
And again they don't get 10-50x on string/hash/method call workloads. I think they're lucky to get 2x in some of those cases.
Well, C hardly is, either...
However a call to a shared library that isn’t linked against your language API is not very expensive as you have a much better handle on the values that are escaping and can make much better optimization choices.
In the Truffle project we are using an LLVM bitcode interpreter that allows us to JIT right through that language boundary and still link to native shared libraries. This means people shouldn’t have to rewrite their C extensions and we can hopefully still run the combination of high level language and C extension faster.
JSC and LuaJIT have simpler ways to deal with calling native code which might do weird stuff.
I think a workload like this is more common in the PHP world. Not saying that others don’t exist, but handling routing, queries, cached content is very different from simply doing mathematical/memory intensive applications.
JIT compilers have different optimizations available like:
Fast inlined heap allocation (normally much faster than malloc/free). V8 even does allocation combining
Transparent ropes for strings
High level alias analysis for hash tables and objects
Inlining dynamic dispatched functions and dynamically loaded functions
Any language can eventually reach that point with enough money, time, and in C's case doing 200+ optimizations with unexpected results.
So there's nothing really funny about it....