scala-cli
scala-cli copied to clipboard
Scripts with instant startup
Is your feature request related to a problem? Please describe.
When running a scala script with native compilation, there is a noticeable delay.
Example: test.sc is
#!/usr/bin/env -S scala shebang
//> using platform native
println("Hello")
I run: time ./test.sc (compilation happens) and again time ./test.sc. I get:
Hello
real 0m0.605s
user 0m0.270s
sys 0m0.244s
The startup time is 0.6s (which (on my computer) actually a tiny bit slower than with JVM compilation).
The documentation seems to indicate that it is possible to get instant startup using native (https://scala-cli.virtuslab.org/docs/cookbooks/introduction/instant-startup-scala-scripts/).
Describe the solution you'd like
This script to finish in a non-noticeable amount of time, not 0.6s. For comparison, on the same machine, a comparable Python script runs 0.03s.
This would allow to write scripts that can be used interactively in the shell, with reactivity comparable to shell scripts or Python scripts.
Describe alternatives you've considered
- Running the natively compiled binary instead (which can be found in a subdirectory of
.scala-build). This means that one has to manually ensure that the compilation is up to date, and also find the file. Not suitable for scripting. - Implementing a wrapper script that checks whether the script is more current than the compiled binary, and possibly runs the compiled binary directly. Problem: depends on the internals of scala-cli (such as the location of the compiled binary).
- Wait 0.6s. For some scripts, that's ok. But for interactive cli use, the delay is hindering the work.
Additional context
#3127 raised the same problem but was closed because (as far as I understood) it raised several issues in one.
if you don't intend to change it that often you can package it to an executable
scala package -o test_sc test.sc
then it will be as fast as you wanted - just with an extra file
I guess this isn't acceptable given the alternative listed
one has to manually ensure that the compilation is up to date
perhaps it is possible to run scala-cli's caching checks quicker than 0.6 seconds? hinting at a missed opportunity for specifically native script files
perhaps it is possible to run scala-cli's caching checks quicker than 0.6 seconds? hinting at a missed opportunity for specifically native script files
I think that there could also be similar room for improvement with Scala.js – or larger, in fact, because it seems that whenever I run a Scala.js script, it tries to fetch something. 🤔
$ ./scala-js
https://github.com/virtusLab/scala-js-cli/releases/download/v1.16.0.1/scala-js-ld-aarch64-apple-darwin.gz
0.0% [ ] 0B (0B / s)
$ cat scala-js
#!/usr/bin/env -S scala-cli shebang
//> using scala 3.5.0
//> using platform scala-js
//> using jsVersion 1.16.0
println("Hello")
$ scala-cli version
Scala CLI version: 1.5.0
Scala version (default): 3.5.0
By the way, here's a small benchmark I did out of curiosity:
Results
$ hyperfine --warmup 3 ./scala-native ./scala-js ./scala-jvm ./python
Benchmark 1: ./scala-native
Time (mean ± σ): 326.6 ms ± 5.4 ms [User: 20.6 ms, System: 20.2 ms]
Range (min … max): 318.1 ms … 334.7 ms 10 runs
Benchmark 2: ./scala-js
Time (mean ± σ): 1.587 s ± 0.111 s [User: 0.036 s, System: 0.022 s]
Range (min … max): 1.509 s … 1.820 s 10 runs
Benchmark 3: ./scala-jvm
Time (mean ± σ): 470.5 ms ± 10.4 ms [User: 157.8 ms, System: 49.1 ms]
Range (min … max): 457.5 ms … 483.6 ms 10 runs
Benchmark 4: ./python
Time (mean ± σ): 17.7 ms ± 0.5 ms [User: 12.2 ms, System: 4.0 ms]
Range (min … max): 17.1 ms … 20.4 ms 148 runs
Summary
./python ran
18.42 ± 0.58 times faster than ./scala-native
26.54 ± 0.92 times faster than ./scala-jvm
89.52 ± 6.72 times faster than ./scala-js