Improve GraalVM native image size / compile time memory consumption when compiling clojure.pprint

Description

In pprint/pprint_base.clj there is a function table-ize which looks up dynamic vars from keyword options. It does so using find-var. Using runtime find-var has negative impact on GraalVM native-image binary output size and memory consumption during compilation, although it does work if the vars are still present after analysis. However, the usage of find-var can be easily avoided by a slight modification in the lookup table write-option-table which is currently a map from keywords to symbols. If we change that to keywords to vars, table-ize can avoid using find-var.

The benefit on GraalVM compilation can be shown as follows. Currently on master, when compiling the below example, the outputted binary is around 30MB (compile time 40s, peak compile time memory usage 1.8GB). With the patch it's only 10MB (compile time 20s, peak compile time memory usage around 1.5GB) (measured on a Macbook Pro 2019 i9)

Deps.edn:

Put this Clojure code in graal-test/hello_world.

Bash script to compile. Set GRAALVM_HOME to the GraalVM distribution.
On my system: export GRAALVM_HOME=/Users/borkdude/Downloads/graalvm-ce-java11-20.2.0/Contents/Home

Some concern has been raised around directly embedding vars in the map and a possibly negative impact on startup time. I've done some testing around this and did not see a significant difference, when using AOT-ed pprint.

Environment

None

Activity

Show:
Michiel Borkent
September 25, 2020, 9:41 AM
Edited

The above patch can also be achieved externally using alter-var-root:

Assignee

Alex Miller

Reporter

Michiel Borkent

Patch

Code

Priority

Major