Hacker News new | ask | show | jobs
by JZerf 1402 days ago
It seems to use a lot of memory which can be unacceptable for many people and can become impractical if you plan on running several programs simultaneously. For several of the problems at https://benchmarksgame-team.pages.debian.net/benchmarksgame/... on the Computer Language Benchmarks Games, it shows the Julia programs as using several times more memory than similar Java programs. It's even worse when comparing to C, C++, Rust, etc...
1 comments

Remember that for those benchmarks, C, C++, and Rust compile the binaries and then run the benchmark, while Julia compiles as part of the benchmark. The memory usage is dramatically decreased if you do a workflow similar to the other languages using something like PackageCompiler.jl to build a binary that is benchmarked. If you treat the other languages as "JIT" and include those factors in the benchmarking process, it's a lot closer.
Thanks, I hadn't noticed that Julia was also doing compilation during the benchmarking and I'm curious if it would be hard to get those benchmarks to be done with PackageCompiler.jl. With that being said, the memory usage still seems very high. For many of the problems, Julia is often using the second most memory of all the programming language implementations being benchmarked and several of those other programming languages implementations (Node.js, OpenJDK, .NET, etc...) also are doing some sort of compilation during the benchmarking as well. I also tried compiling several of the C programs with GCC and GCC usually only used ~30 MB of additional memory so even if you add that to the the memory usage of the C programs, it's still much less than the Julia programs. Using PackageCompiler.jl does look promising but that does add another step which looks to be slightly more involved (looks a bit comparable to using profile-guided optimization) than compilation steps for other programming languages and some could see that as another problem for using Julia in real projects.
Yes, the size in memory is definitely an issue. Do keep in mind that right now, the julia executable more or less just has to load all of LLVM as a shared object into memory, since we might compile stuff at any time. That alone adds ~84M of overhead on my machine for the current libLLVM14 shared object. There's probably some other stuff I haven't thought of OTOH. The (non-minified) runtime itself is 244K at the moment, which can probably be slimmed down further. There are currently efforts underway to statically compile more stuff and hopefully introduce a more traditional static linking approach, but it takes time & lots of effort.

Still, a large chunk of the memory being spent is not in the code that's produced or in the allocations happening in the code, but libraries that are loaded but not required. It's one of the downsides of focusing on interactivity first. The benchmarks in benchmarksgame don't reflect that, which I guess is up to interpretation/what's required - if the total amount of memory is a concern it's an important figure, if you only care about your core algorithm not having inherent allocation/memory problems, you probably won't care about the compiler chain as much.

In the past the benchmarkgame people haven't let us use PackageCompiler. The big memory gain would be that you could skip loading things like LinearAlgebra and the other standard libraries that aren't being used (but which you are still loading code for).
I think some more effort should be made in getting the default memory usage down to a more reasonable level. This site https://programming-language-benchmarks.vercel.app/problem/h... shows a simple Hello World Julia program as using 169 MB of memory (and I saw similar memory usage on my computer running '/usr/bin/time julia -e 'println("Hello World!")'') which was the third worse of all the programming language implementations that were tested.
Oh definitely agreed. A lot of this is because Julia always loads BLAS and LLVM, so it's like doing `import numpy; import numba; print("Hello World")` and then noticing most of the startup time is loading numpy and numba. But it's a hard question because if BLAS isn't always loaded with Julia, its previously core scientific computing case is impacted. As it has been growing to be more widely used in a general purpose case, these kinds of assumptions are having to be revisited.

One can of course remove this in the compilation stage of PackageCompiler because PackageCompiler builds a new system image, and where BLAS is loaded is in the system image, so you can create a new from-scratch system image that is more lean. However, the tooling isn't quite there yet: right now the main way that's documented is something that extends the default system image, hence the large binaries. There's StaticCompiler.jl which does tree shaking so it makes small binaries, but it doesn't support most of the Julia runtime right now so it's limited in the codes it can handle. So right now the foundation all exists and it's at a usable state but definitely needs to improve.

Absolutely! This isn't high priority but there is some very low hanging fruit. It's not that reducible though since llvm is 84 of those megs and they have to go into memory if you want to be able to generate new code.
While this is true, it's also true that Julia currently brings more into ram than it should (and brings stuff in earlier than it should). The best example of this is that we currently allocate buffers ahead of time for matrix multiplication temporaries (even if matrix multiplication is never performed in the program). We do need to fix that type of thing eventually.