Hacker News new | ask | show | jobs
by pas 2223 days ago
Is Julia really just as dynamic? Isn't the problem with Python that the low-level C API still needs to be respected during JIT, which just kills performance. (That's why PyPy largely doesn't support it, right?)

Even JS doesn't suffer from this, because folks can't just load V8 extensions in their browser, and Node went through quite a few NAPI versions - forced by V8 changes.

That said, of course it'd be possible to speed up Python/CPython with pouring a lot more money into it. But ... the CPython codebase is already old and has many problems, a lot of backward compatibility gotchas, and relatively few people willing to work on it. Because there's not a big reason to do so. Whereas with JS Google (and thus Mozilla too) was very incentivized to make it fast.

2 comments

Julia (and likely Dylan and CL which are all similar languages) are not nearly as dynamic as Python. Or more accurately, they are nearly as dynamic, but writing code like that is not idiomatic and it will lead to performance similar to Python.

The most important factor is that those languages were designed with JIT in mind, with a clear separation of compile time and runtime. Not only the macros, which are low cost abstractions, but also how all the dynamic parts of the language can actually be resolved during this period, like type inference and static/multiple dispatch, which are enabled by it's carefully crafted type system that bridges the dynamic world and the static world. Idiomatic Julia is not strictly a dynamic language but a superposition of many static programs, one of which will be selected for each runtime pass.

So changing a variable type in Python has basically no effect, but in Julia , while allowed, it causes what's called type instability and the compiler will be pessimist and create a dynamic box for the type that can't be optimized. Which is also why global variables are so damaging to performance in the language since they can't be inferred. Defining or redefining a function (not a lambda) or types or importing a library dynamically during runtime is another feature that is also allowed, but avoided in practice since they'll invalidate the JIT cache and force a recompilation. The culture of performance aware programming is the second key factor in their speed.

Julia, I am not sure how far its dynamism goes, but Dylan, Common Lisp and Smalltalk certainly.

You can even at any point in time stop execution in the debugger, rewrite part of the world and just press continue as if that was how the code was originally written to start with.

> You can even at any point in time stop execution in the debugger, rewrite part of the world and just press continue as if that was how the code was originally written to start with.

Bit of a straw man, because you wouldn't do this regularly in code. Python on the other hand is a relatively large language at this point, and plain idiomatic python code leans relatively heavier on JIT unfriendly constructs compared to the other languages mentioned. Meanwhile, CL has a whole concept of "compile-time" that doesn't really exist in python. Hence the "perversely" part.

PyPy has used similar tricks as Smalltalk, Self, and JS/V8, many which were old hat in the 90s, but PyPy demonstrates that writing a performant JIT with reasonable memory requirements for real world code is much harder for Python.

For me the only thing that PyPy sadly demonstrates is that the Python community doesn't care about JIT support and anyone that wishes to use languages that embrace JITs should look elsewhere instead of having a continuous disappointment.