top | item 27280174

Julia 1.6 addresses latency issues

177 points| leephillips | 4 years ago |lwn.net | reply

157 comments

order
[+] smabie|4 years ago|reply
So I used to be a big proponent of Julia, and in some ways, I still am. But I very recently tried to write a high performance production system in it, and was sorely disappointed. The tooling is just so buggy and it's clear that the community isn't really interested in using it for anything besides modeling/research in a Jupyter notebook.

Things that kind of suck about using Julia for production:

1. Never could get Revise to work, had to restart my REPL everytime I changed any code. Even though Julia 1.6 was a lot faster than 1.5, it still took too long.

2. Couldn't find a static type checker that actually worked (I tried JET and StaticLint). I feel like static typing is just so important for a production system, but of course the community isn't really interested because of the research focus.

3. Editor tooling. The LSP server absolutely sucks. I first tried using it with emacs (both lsp-mode and eglot mode), but it would crash constantly. I think switched to VSCode (much to my chagrin), and that worked marginally better though still very poorly. It was clear that the LSP server had no idea what was going on in my macro heavy code. It couldn't jump to definitions or usages much of the time. It could never correctly determine whether a variable was unused or misspelled either. Coupled with the lack of static type checking, this was extremely frustrating.

4. Never felt like the community could answer any of my questions. If you have some research or stats question, they were great, but anything else, forget about it.

Will all of that being said, I do still use Julia for research and I find it works really well. The language is very nicely designed.

All and all, I decided to ditch Julia and decided to go with Rust (after some consideration of OCaml, but unfortunately the multi-core story still isn't there yet) and am a lot happier.

[+] east2west|4 years ago|reply
I agree with most of what you said and share your frustration with the tooling of Julia. However, I am not sure how well I would expect a static checker to work for Julia. Julia after all is a dynamical language, and while you may disagree with that choice, the dynamical typing permeates the language. There is no pattern matching and no language features to manipulate types, for example. Julia's AST and IR share a lot in basic data structure thanks in large part to Julia's dynamical nature. Since adding static typing to Julia at the current stage of its development would be almost an upheaval, I am not counting on it.

This means there is an upper bound to how good the editing and refactoring tooling will be. I suspect the best will be a little below Pythong's tooling, because Python's class helps in disambiguating methods.

One feature of Julia I think could be improved upon is the `include` statement to import code, similar to C's `include` macro directive. This makes finding functions within a package an absolute nightmare. I think this also restricts LSP's ability to find definition and usage since this tends to make Julia packages one big source file as far as the compiler is concerned. I saw that in Julia's compiler code, the core developers include C source files, not header files mind you, in other C source files, so perhaps the feature stems from their personal preference. Python's file-module may be too restricting, but Julia's including is too loose.

[+] snicker7|4 years ago|reply
Your concerns are absolutely valid. Julia tooling is lacking, and tooling quality can be more important than language quality. There is a reason why Java is so popular.

I feel that most of your points can be addressed if the compiler's "abstract interpreter" (static analysis) procedures were exposed and reliable/stable. Some packages (e.g. Mjolnir.jl [0]) attempt to re-implement it. Others (e.g. JET.jl [1]) try to hook into Julia's undocumented/private compiler internals (CoreCompiler). Rightfully so, only the most intrepid are willing to do this.

[0]: https://juliapackages.com/p/mjolnir

[1]: https://juliapackages.com/p/JET

[+] jampekka|4 years ago|reply
It's sad to see that the Julia ecosystem does not address these issues at all. Maybe Julia people are in some kind of bubble of people who like Julia and generalize that to all potential users and contributors. The true process is probably that people with other workflows (eg. non-REPL/Notebook) and past experiences (esp. more "general purpose" languages) just give up and are never heard of again.

I've ranted about very similar things for some time now, and had some fruitful discussions, and I even offered to help to try to scratch some of the itches me and others are suffering from. I've now mostly given up too.

It's a bit sad for me. I think Julia has many things right and the core concepts are potentially revolutionary. But for me it seems that Julia ecosystem is a bit too jealous of their discovery to let it free. Weird.

[+] tbenst|4 years ago|reply
I use Julia as my main driver these days and have shared some of this experience but not all

1) I use VScode and have had 0 problems with Revise. It Just Works when using the Julia extension + built in REPL. I actually prefer the Julia environment to Python in VScode, I have way fewer problems when doing a Notebook-like workflow where I’m writing library code at the same time

2) Agreed, I also wish there was a better story here. I’m constantly frustrated by how little static support there is. It’s getting better though, eg precompilation in 1.6.

3) I haven’t had any issues here outside of the occasional update to VScode Julia extension that botches things

4) I’ve had quite a lot of luck on discourse and GitHub issues, as well as slack for the occasional small question

Rust is great for use cases where you have specific resource management needs, although seems an odd choice for general purpose scientific computing.

[+] xiaodai|4 years ago|reply
What you've pointed out might all be valid. But they seem to be issues with maturity. When Python was at a similar age, did it have all these issues worked out?

Not sure if you can generalize it to "Julia community isn't interested".

If we have more ppl liking Julia and using it for general purpose computing (which it is capable of), then more of these tools will become mature overtime.

Also, Julia is not in the same niche as Rust though, it's more like a Python, so not sure if the comparison is apt.

[+] Tainnor|4 years ago|reply
I would also add:

5. The module system is very primitive.

6. The testing framework is extremely barebones.

I agree with your assessment, Julia is great for crunching numbers etc., but I wouldn't write a whole application in it.

[+] diragon|4 years ago|reply
How did you cope with the lack of REPL on Rust's side?
[+] gugagore|4 years ago|reply
It is amazing and frustrating to me how much latency affects my productivity. I wish I could more effortlessly switch between tasks, or just meditate and relax while I wait for something I just did on the REPL to finish. But I don't. More often than not, a 30-second delay to e.g. plot something destroys my ability to stay in a productive zone.

I have been using Julia 1.6 since the release, and I'm so grateful not only that some computations run a bit faster, but that the interactivity is so improved.

Even seeing a progress bar can help me stay focused, because it can be fun to watch (parallel precompilation is especially fun). When a command just hangs, I feel left in the dark about how much boredom I'll have to endure.

[+] ssivark|4 years ago|reply
Very interesting UX observations on interactive programming.

Kinda like mirrors in waiting areas, I wonder whether judicious logging messages about the compilation process (not a wall of text, but just enough) will serve to keep users engaged while also educating them about the compilation happening on the backend. That will help users feel more agency, and also improve their mental models of how to structure their code/activity for faster compilation.

[+] globular-toast|4 years ago|reply
This is why git was such a game changer. Making a commit to SVN took a considerable amount of time, especially back in the day on slow internet connections. Making a commit with git is generally instant and doesn't break flow. It changes the way you work. People used to avoid committing with SVN, sometimes doing it only once a day. That seems completely insane now.

I have very little tolerance for latency in my tools. It's one of the top deciding factors for me when choosing which tools to use. It's that important.

[+] Mauricebranagh|4 years ago|reply
Well as one of the aims as I understand it for Julia was as an alternate to Fortran.

You should consider your self lucky when I started the compile link process took a while and that is assuming you had real time access.

I recall one of my colleagues who was running her code on an ICL at AWE (Underwater Weapons Establishment) coming into the terminal room logging in and sighing "48 jobs in GEORGE ahead of hers.

A year later we brought a Pr1me Super Mini which made things a lot faster.

[+] Buttons840|4 years ago|reply
I'm a big fan of Julia. It does live up to its speed claims. I've implemented the board game Go in Python, Rust, and Julia and Julia is definitely closer to Rust in speed. Same algorithms were used for all implementations.

Julia's time to first plot still has some problems. The Plots library can build animations, but the time to first animation on my computer is like 10 minutes, and the time to second animation is another 10 minutes. Probably just a bug, I haven't found any other case that takes so long.

I've also mentioned before that a reinforcement learning algorithm I ported from Python/PyTorch to Flux was faster, not because of training times, but because of all the other stuff (and RL has more "other stuff" than supervised learning) that goes on outside the core training loop is so much faster.

[+] clarkevans|4 years ago|reply
Multiple dispatch and generic programming make Julia a productive language to work with. However, a given program may have unnecessary function specializations (which affect startup compile time) or unexpected dynamic dispatches (which affect runtime performance). These can be addressed with some important development patterns: checking for type stability via @code_warntype, using opaque structs or @nospecialize when appropriate, etc. I've found the Julia community to be very helpful with regard to performance on the forums, slack, and zulip.
[+] throwaway894345|4 years ago|reply
> I've implemented the board game Go in Python, Rust, and Julia and Julia

Oof. I reread this several times consecutively as "I've implemented the board game in Go, Python, Rust ...".

[+] lmm|4 years ago|reply
> I'm a big fan of Julia. It does live up to its speed claims. I've implemented the board game Go in Python, Rust, and Julia and Julia is definitely closer to Rust in speed. Same algorithms were used for all implementations.

"Closer to Rust than to Python" is a wide range. Almost any non-scripting language (e.g. Java, OCaml, Haskell, Dylan...) would qualify, and that's normally not enough to give them a reputation as "fast".

[+] vavooom|4 years ago|reply
Do you have any documentation / Github repos where you build those Go implementations? I am a huge fan of the game and would be curious to see how you built it, specifically in Python / Julia.
[+] dunefox|4 years ago|reply
> but the time to first animation on my computer is like 10 minutes

Have you tried 1.6 already? I find it's substantially faster.

[+] xiaodai|4 years ago|reply
what's your ogs id? I challenge u
[+] up6w6|4 years ago|reply
I use and love Julia but I really wanted to see the general purpose language that is claimed. On one hand, you see amazing scientific libs like DifferentialEquations.jl, on the other side, things like the PackageCompiler.jl mentioned just sucks at generating binaries for daily basis.
[+] krastanov|4 years ago|reply
Isn't "generating binaries" just as bad for other interpreted (interpeted-ish) languages? If you generate a "python binary", you need to package python with your binary. Same for perl/ruby. It just seems weird that people expect julia to be able to do that. It is cute that PackageCompiler.jl exists and it is cute that more AOT compilation work is being currently done, but it seems crazy to expect Julia to be good at making binaries (and I would say that about python and perl too).

And by extension, it seems weird to me to complain that Julia is not a general purpose language because it can not generate binaries. What stops me from making the same statement about python, which is definitely general purpose?

[+] adsharma|4 years ago|reply
For me the issue manifested as a 10 sec latency to format a Julia file using Format.jl

Solved via flags to disable JIT and brought it down to a couple of secs. Native binary would be much nicer.

[+] enriquto|4 years ago|reply
Two seconds to process a tiny text file enters well into the realm of "completely unusable" in my eyes.

It wouldn't be so bad if the Julia developers acknowledged that this is a valid concern (that they are not dealing with it right now for whatever reasons) and that the ecosystem will not be considered complete until this fundamental problem is solved. But this is infuriatingly not the case. Instead, they tell you that you are "holding it wrong" and that this is not really a problem, that your usage is "niche", that the interpreter is alright as it is, and that the time to first plot is unlikely to ever go below a hundred milliseconds. I find it really depressing for the language itself is incredibly beautiful. My only hope is that an independent, fast and unix-friendly implementation of the language arises, thus freeing the reference implementation of the efficiency burden and allowing it to be simpler. Something like the lua/luajit split.

[+] krastanov|4 years ago|reply
I am very confused by the claim in the first sentence of the article: "On March 24, version 1.6.0 of the Julia programming language was released. This is the first feature release since 1.0 came out in 2018". How is 1.6 a "feature release", but 1.1-1.5 are not!? Especially given the enormous new set of multi-threading features in 1.3.

Edit: ah, thanks for the response, it seem I just do not know the difference between "feature" and "timed" release.

[+] leephillips|4 years ago|reply
That’s the terminology used in the development process. The releases > 1.0 and < 1.6 are called “timed releases”. It doesn’t mean they don’t contain any new features.