apple / pkl

A configuration as code language with rich validation and tooling.
https://pkl-lang.org
Apache License 2.0
9.92k stars 259 forks source link

UPX the binary so it would save bandwidth #30

Open kokizzu opened 5 months ago

kokizzu commented 5 months ago

especially for 3rd world countries where internet is slow

upx pkl
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2020
UPX 3.96        Markus Oberhumer, Laszlo Molnar & John Reiser   Jan 23rd 2020

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
  87137256 ->  26604364   30.53%   linux/amd64   pkl

Packed 1 file.
holzensp commented 5 months ago

I certainly like the idea, but I'm a little hesitant about this (from upx.github.io):

Programs and libraries compressed by UPX are completely self-contained and run exactly as before, with no runtime or memory penalty for most of the supported formats.

I have not had the chance to test, but I think this statement ignores startup time, which we want to be very mindful of. If you know of some benchmarks around this topic, I'm happy to look at it further.

Releasing both the "normal" and the compressed version is also an option, of course, but that makes bug reports (especially around distribution) harder. We are working on getting onto newer versions of GraalVM, which also promises significant reductions in binary size.

jamesward commented 4 months ago

Very basic benchmark:

pkl-k8s-examples/pkl/basic $ time pkl eval -f yaml frontend.pkl

...
real    0m0.318s
user    0m0.300s
sys 0m0.016s

With upx -9:

pkl-k8s-examples/pkl/basic $ time pkl-upx eval -f yaml frontend.pkl

...

real    0m0.580s
user    0m0.531s
sys 0m0.045s

So definitely some overhead but not sure if it is acceptable amount.

Another option since some of Pkl is written in Kotlin is Kotlin/Native which produces much smaller binaries. But that'd be a much larger re-write since all of the JVM dependencies would have to be replaced and there may not be existing alternatives yet. Just for reference, a very basic "hello, world" with Kotlin/Native (source):

hello-kotlin-native $ ls -al build/bin/linuxX64/releaseExecutable/hello-kotlin-native.kexe
-rwxrwxr-x 1 jw jw 468376 Mar  3 09:18 build/bin/linuxX64/releaseExecutable/hello-kotlin-native.kexe

hello-kotlin-native $ time build/bin/linuxX64/releaseExecutable/hello-kotlin-native.kexe
hello, world

real    0m0.005s
user    0m0.001s
sys 0m0.005s

hello-kotlin-native $ upx -9 build/bin/linuxX64/releaseExecutable/hello-kotlin-native.kexe
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2024
UPX 4.2.2       Markus Oberhumer, Laszlo Molnar & John Reiser    Jan 3rd 2024

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
    468376 ->    142188   30.36%   linux/amd64   hello-kotlin-native.kexe  

hello-kotlin-native $ time build/bin/linuxX64/releaseExecutable/hello-kotlin-native.kexe
hello, world

real    0m0.009s
user    0m0.009s
sys 0m0.000s

Side note, that with Kotlin Multiplatform, you could have both the native and the JVM library outputs so Pkl wouldn't lose the JVM library like they would if they went Rust, Go, etc.