Julia vs R vs Python

This is mainly an LLVM issue and not a Julia issue. Yes, LLVM can automatically SIMD-vectorize code in some cases. You can enable SIMD for a particular loop by using the @simd macro, and you can also turn on SIMD and other optimizations by running julia -O3.

However, it isn’t always successful. For example, on the fractal code above, @simd made no difference and julia -O3 actually makes it slower on my machine, not faster. (Again, an LLVM issue not a Julia one.) This particular loop is going to be hard to automatically SIMD vectorize because of the dependencies in the innermost loop, and the fact that different z require different numbers of iterations in the innermost loop.

(SIMD vectorization has absolutely nothing to do with the language performance differences in this thread!)

To get better SIMD vectorization of this kind of fractal code is tricky, I’m guessing that for the next few years you would have to do things manually e.g. via SIMD.jl. (I suppose you could restructure the loops to speculatively execute multiple iterations at once, or iterate for multiple z at once, and then backtrack once escape is detected. I seriously doubt that any compiler will ever be able to do this for you in the foreseeable future.)

2 Likes

Thanks for all your answers! I’ll incorporate many of the learnings from here and the included links, and am especially happy for the big performance improvement from using abs2. :slight_smile:

FYI, I just tested using PyPy and it runs in about 11 seconds. ~5x slower than Julia

(Note that PyPy is, unfortunately, pretty hard to use for technical work because it is incompatible with many of the key scientific libraries, from SciPy to TensorFlow. One of the key difficulties for Python, Matlab, and R compilers is that it is hard for them to make things faster without breaking backwards compatibility.)

4 Likes

11 Seconds?
That’s really nice!

I think it is only ~2.5 slower than Julia (As I think PyPy is single threaded).

@stevengj, I wish someone would reconsider the compatibility thing.
Really, move forward, make things move forward.
Compatibility isn’t the most important thing as long as you keep a way to run old code.

For instant, Mathworks have MCR of all versions.
Since it is there, I would be happy if they break compatibility in the name of performance.

Steven, Bullseye.
Panasas (storage company) haev an excellent term - Time to Solution. That is what counts - how fast you can get the results for your bank’s overnight risk analysis run/ the simulation which will win your Nobel Prize/rendering your Youtube cat movies. (Delete as appropriate).
I will counter with ‘Good enough for Jazz’ - I guess most of us mortals start by writing a ‘quick and dirty’ script which is only meant to be run once, then ends up taking on a life of its own.
(A cat just came to sit on my keyboard - cat kind are taking revenge for my remark above)

I guess though - stretching the Jazz analogy, the piano IS important and Julia gives is a good piano to start with.

I can’t tell from this if you’re encouraging the Python community to drop compatibility and move forward with PyPy (this is very unlikely to happen since the core developers remain committed to CPython as the implementation of Python), or if you’re exhorting us (the Julia community) to reconsider some compatibility thing.

On the subject of compatibility and how language design choices make it hard for some languages to run fast, it seems to be generally very poorly understood just how hard the designs of languages like Python and R are for really high performance implementations. If you’re interested, here are two talks on the subject:

Armin Ronacher (one of the creators of PyPy), “How Python was Shaped by leaky Internals”:

Jan Vitek, “Making R run Fast”:

This talk contains the following key quotation by Jan:

I haven’t seen a language that is as hard to optimize as R. Somebody should give the R designer that particular prize as probably the hardest language to optimize… Compared to R, JavaScript is a beauty of elegance and good design.

The title of this talk is largely aspirational (they haven’t made R run much faster), although Jan’s research lab has a variety of projects trying to improve R’s performance.

12 Likes

I meant that compatibility is over rated.
Sometimes it gets in the way of the real object of the project and becomes the object by itself.

For instance you can see Intel is now starting to pay for its fanatic compatibility religion when new architecture which doesn’t hold on their shoulders ~35 years of compatibility and taking advantage of lessons learned are kicking it.

So my point is that I hope, in the future, if compatibility issues stand in the way of Julia to achieve great performance improvements the choice would be to freeze a version which is compatible for anything until this day and create a new point.

I understand it should be something which promise great improvement (No one would break is for meaningless improvement), I just hope compatibility won’t become religion and the main objective of the project.

If Julia objective is to break the 2 languages problem, it means it should do what’s needed to achieve that.

That’s called a major release.

Read my post again and see it is not.

If it was, give me the credit I would say so.

But by definition… it is… You exactly described what a major release in semvar is: a breaking change. The problem with Python was that Python 3 took a very long time after Python 2 and it was almost impossible to support the two. Julia has a lot of mechanisms in place (depwarns, Compat.jl, etc.) to make major releases easier to handle. But yes, I was just mentioning that you’re just saying “I think we should have a quick 2.0, and other major versions should have a steady and quick release cycle” in a more verbose way. This is something that has been mentioned in previous roadmap talks and I think that the Julia community tends to be less conservative than something like Python with breaking changes. Though it will be nice to have a 1.0 so this can start happening in “bursts” every few years instead of every few months…

Honestly though, there’s so much that can be done for scientific computing that doesn’t require a breaking change that I kind of wonder what’s left. What kinds of breaking changes are you looking for?

1 Like

You insist and I’m saying this is not what I meant.

Look at the video of Armin Ronacher @StefanKarpinski posted.
You can see a list of things he mentioned that are the way the are for years and nobody will change them in the name of compatibility which hurts Python speed significantly.
In that sense even Major Release didn’t go far enough because of compatibility (Namely keeping compatibility).

What I meant is not small fixing around the corners which might break some old code.
My point was a policy of the language to stay faithful to its objective and not compatibility.
What is need to be broken in order to build it right in the second (Third, fourth, etc…) will be broken.

Python won’t break compatibility to make things faster because that’s not what it’s objective is. The kinds of changes in the video are perfectly reasonable things to add for a major release, but they won’t be added to Python because its main target user groups are looking more for the features that would be lost due to speed constraints than the speed itself. Speed is pretty clear to Julia’s objective, so bringing up the fact that Python doesn’t make breaking changes in the name of speed as a reason to suspect Julia won’t doesn’t make sense.

Changing all . operators to use into an anonymous function and broadcast in the name of performance is pretty huge and breaking change (which had a lot of casualties like Knet.jl). Changing all anonymous functions to be individual callable types which autospecialize in function calls is a huge and breaking change but resulted in fast anonymous functions. So of course Julia has a commitment to doing what it’s already doing.

But adding NamedTuples to allow keyword argument dispatching, giving a fast path for small unions, etc. are all upcoming and (mostly) non-breaking changes which add a lot of ways to optimize speed. Lots of other things, like macros for declaring local non-aliasing scopes, can be added to give speed in a clear and concise way without breaking code. Most of the changes that are lined up which are speed improvements (and that people ask for) actually seem to be non-breaking. So again, if you want to be push the breaking agenda, what exactly are you proposing to break and why?

1 Like

Here’s the thing: we’re just not in the same situation as other high-level dynamic languages with regard to legacy making things slow. R, Python, Matlab, etc. have decades of assumptions and features based on the internal details of a slow implementation. Julia was designed to run fast with a JIT in the first place. We don’t have to painfully remove features that make it hard or impossible to generate fast code – we’ve never added those features in the first place. If there are language changes that we can make in the future that can make Julia even faster, they will be at the top of the list of changes to consider in Julia 2.0. But the truth is that there are so many pure optimizations (by definition, non-breaking) that we haven’t even started to experiment with that it will be quite some time before we need to break things for performance.

3 Likes

Well, you know, years will come and go and people will learn new things.
In retrospect, in few years, something which is right today might be sub optimal.

But the spirit you’re conveying with your words that’s exactly the policy Julia should stick to.
Julia is here to be at the front of what’s known in order to solve the languages problem.
It will do, redo, bread and rebuild what’s needed for that.

I think in the years to come this policy will make sure Julia won’t be another one of many, it will shine as different (Hopefully different and successful).

@StefanKarpinski, Any chance for more videos in the spirit you posted above?

I’m not a specialist of those things but I really find it interesting.
Anything on other languages architecture? Anything more on Python, Julia?

Thank You.

Not off the top of my head, but I’m sure there’s more stuff out there.

For me the thing about Python is not so much that it’s badly designed (it isn’t) but rather that it has been radically misappropriated for use in things that it has no business doing (i.e. scientific programming). It is a testament to Python’s good design that this program has been successful at all. Ultimately this has left us with a bad situation however, so it’s past time that it stop.

Oh man, that’s a hell of an insult.

3 Likes

No even on Julia?

@ExpandingMan,
I don’t think the talk above talks in the context of Scientific Computation.
It is in general.
It doesn’t prove it was designed wrongly, but I hope there are really good reason for that.

You left in a typo when introducing the abs2().
It should be if abs2(z) > 4

FYI: I tried with adding two numba @autojit decorators to the python version and it ran within a factor of 1.5 of the Julia code when using abs in Julia and Python. Julia is about 2.5 x as fast as numba when using abs2 for which I did not find a numba/python equivalent.

Wow,

Could you share the code?
So Python can get really fast.