4 ms·
I'm not super familiar with the ecosystem, but does the GraalVM compiler provide a way to "tree shake" dependencies? This past year I wrote a rather simple des
by geokon 6y ago
I'm not super familiar with the ecosystem, but does the GraalVM compiler provide a way to "tree shake" dependencies?
This past year I wrote a rather simple desktop app (JavaFX) for work using Clojure. But Java by default uses RTTI - and Clojure by extension does as well - the dependency tree would balloon my final executable. For instance, I'd bring in some CV library like BoofCV to do some very basic image manipulation, but all of BoofCV and its dependencies would get dragged in. Hundreds of megabytes of junk.. So you either have to just accept you have a gargantuan executable or you have to use some smaller subpar libraries to do what you want. But it seems unfortunate the ecosystem pushes you to use less/smaller dependencies instead of using robust large ones.
I understand the reason behind it. The java compiler has no way to ensure which classes will be used and which won't be b/c crazy things can happen at run time. Maybe with all the work on GraalVM people will move their libraries to not use RTTI as much? I haven't had a chance to hook up Graal yet (I think it doesn't play nice with JavaFX.. or maybe that's old news) - but it's unclear if it'll slim down the final binary. If it does - then this potentially a game changer for "deliverable" executables :)
PS: You can manually go in and disable sub-dependencies.. but it's ugly and incomplete. I got Clojure/JFX/Java to compile down to something like 60MB - but my app is simple and it really should be more like 2MB.
- chrisseaton 6y ago> I'm not super familiar with the ecosystem, but does the GraalVM compiler provide a way to "tree shake" dependencies? Yes it does whole-world analysis and only compiles in classes, methods, and fields, which are actually used. The executables do have a minimum size, because the GC code for example doesn't get any smaller, but I think 2 MB is around the area of what can be achieved, yes.
- Chris2048 6y agoIs there more terminology that means "to tree-shake"? I understand javascript does tree-shaking, mainly in the context of code-minifiers, and certain languages do "path optimisation" usually at runtime - but I'm not sure how to describe the removal, and modification[0] of code (say, interpreted code) outside JS. I'd like to "tree-shake" python in order to see what % of code in it's deps is actually used. [0] e.g removing static parameters, replacing fns with lots of cases into multiple fns etc.
- the_duke 6y ago> Is there more terminology that means "to tree-shake"? Yes, everyone else calls this dead code elimination. [1] (the custom term isn't completely unreasonable, since tree shaking is somewhat different from how compilers do DCE) https://en.wikipedia.org/wiki/Dead_code_elimination https://en.wikipedia.org/wiki/Dead_code_elimination
- Chris2048 6y agoThat page describes "dynamic" elimination, but let's say I call sqrt(x) in my module, but for a fixed value of x - in that case I can just replace the whole fn with a fixed value, but it would require me to detect that the fn is deterministic. Would that still count?
- geokon 6y agoAh okay. To me "tree shaking" was implicitly talking about the dependency tree and removing unused library dependencies. While "dead code elimination" would be a "deep" clean done by a linker when making a static binary (mostly C/C++ land..). There you're looking at a finer granularity than libraries/compilation-units. That's necessarily a bit trickier and I wasn't even thinking that far. But it seems the GraalVM compiler work on this level.