Are there any fundamental parts of Julia's design or implementation that could limit its performance?

Consider two programs, one written in Julia and one in, say, C++. The Julia program is well written: no type instabilities, not too many allocations, bounds checks disabled, etc. The two programs are structurally similar, i.e. same algorithms, same datastructures.

We know that for relatively simple, low-abstraction code - e.g. loopy numerical stuff - the Julia program will run at pretty much the same speed as C/++. This is not that surprising: there isn’t much subjectivity on how to translate simple code to LLVM IR, and once it’s in LLVM’s hands (with all the relevant type information / other metadata), it should produce pretty identical machine code.

My question is this: for a richer / wider domain, are there any cases where Julia’s design or implementation could fundamentally limit its performance, assuming a roughly equivalent level of programming abstraction in the two languages? (Though examples without this assumption are also interesting.) Are there are any abstractions that would be low or zero cost in C++ but would necessarily be higher cost in Julia due to the language’s semantics or structure? Are there any compiler optimizations that could never be applied to Julia code, even if we wanted to? (N.B. some of these design decisions may be deliberate - some abstractions are worth the cost!).

By “domain”, I mean any set of programming abstractions, and computations of any nature. Examples off the top of my head: data structures with lots of references / indirection, web servers, string manipulation, networking, multi-threading, graphics, lambdas, closures…

One obvious difference is that Julia is garbage collected - let’s ignore that.

For context: I know a decent amount about the design of the two languages, have written a decent amount of code in both languages, know a fair bit about compilers etc. After thinking about the question for a little while, no example immediately comes to mind, but I haven’t tried doing everything in both languages, and there are people who are much much more familiar with both languages’ designs and internals than I am.

Looking forward to hearing your thoughts!

Julia allows aliasing, but so does C++.

Fortran does not.
See Faster than C ― Andreas Zwinkau

Thanks, nice link! Of course, runtime optimisation is another obvious thing that Julia at present can’t do (but sort of could in theory… ? Has this been discussed before somewhere?).

I’m also not 100% sure about how fundamental the aliasing problem is, considering that I saw quite a bit of work going into a noalias macro, that will tell the compiler that there is no aliasing :wink:
Not sure if that’s a proper fix in your view, but it seems to get us the best of both worlds!

1 Like

TCO - nice example, hadn’t encountered the lack of it yet.

Can you elaborate a bit on this please? I’ve been loosely following the new multi-threading work, but haven’t dug into all the details.

@noalias sounds great if it could work!

I’m kind of the wrong person to ask :smiley:
Details may be wrong, but as I understand it, you currently simply don’t have fine grained control to spawn threads, since you have a fixed threadpool, and you need to use those threads in a sync block.
That simply doesn’t allow for more complex threading patterns.

I think the new threading will greatly improve the control you have, but I’m not sure if it is only an improvement over the current situation, or if it actually means that Julia will be able to compete with C++ in terms of threading flexibility & performance.

I hope this isn’t set in stone, otherwise GPU event waiting is going to be painful to implement for AMD GPUs (which block an entire thread)…

I personally haven’t seen anything that indicates that it’s impossible to add the ability to spawn and stop threads; it’s certainly a difficult feature to implement, but I highly doubt it’s impossible due to some character of Julia itself.