Hacker News new | ask | show | jobs
by RyEgswuCsn 1904 days ago
Yes I get your point. I guess I should have phrased my first question like the following

1. Can unoptimised Julia code run faster than unoptimised Python code (with numpy being used to do the heavy lifting)?

Let's say one is prototyping some algorithm so iteration speed is more relevant than running speed. Then one can choose either Julia or Python (with the help of numpy perhaps) and get an implementation in similar timeframes. So Julia won't necessarily be more attractive here.

Now if the prototype proved that running speed is very critical to the successful application of the algorithm, then it would mean the developer now has to optimise the hell out of it. One can either:

1. Optimise the Julia codebase, if Julia was used to prototype, following the many tips and tricks available (e.g. type stability, various macros, etc.).

2. Port the algorithm to C/C++, applying the many performance best practices that people have accumulated over the years.

So if the optimised C/C++ port is capable of being any faster than the optimised Julia code, then the rational choice would be to port the implementation using C/C++; it would also mean Python would have some advantage over Julia in the prototyping phase too due to its popularity. Otherwise I'd agree that using a single language to both do prototyping and production is the best.

1 comments

This depends on what you mean by '(un)optimized code'. Because there's a difference between unoptimized and naive code.

'Unoptimized' code should still observe most of the performance tips in the manual (such as avoiding globals and type instability), while 'naive' code frequently does not. With some experience, you never write naive code, even for quick prototypes.

In those cases, Julia should outperform other dynamic lanuages significantly, and approach static languages in most cases.

Proper optimization means going in and removing allocations, ensuring that operations vectorize (simd), tailoring data structures for performance, adding parallelism etc. In the latter case Julia should virtually _always_ match static languages closely, otherwise it merits investigation.

Well there is no type stability or scoping rules to worry about in Python, so just for the sake of comparing the two, I was indeed thinking of 'naive' Julia code vs 'naive' Python code.

The thing with Python is that 'naive' Python code is already pretty close to 'unoptimised' Python code, so one can write naive Python code with numpy and still ends up with not-too-shabby performance, provided they chose an efficient algorithm, of course. In other words, there are not as many performance mistakes one can make with Python (perhaps because it can't get any worse). I imagine that's also why so many Python users who tried Julia were disappointed that direct translations of their Python program fail to perform as fast as advertised.

The point is, once you've gotten used to Julia you tend to write good code most of the time without even thinking about it. And that good code still "looks good," meaning it takes advantage of Julia's expressiveness and brevity. Understandably, newcomers make many more performance mistakes.

So there's often a huge difference between "unoptimized code" (something written by an experienced developer who's deliberately taking the easy way out) and "naive code" (something a newcomer might write). There can literally be orders-of-magnitude performance difference.

I agree that there isn't as much to learn about Python. But of course that's largely because of the gap in opportunities.