pkgx: tea --magic is slow 🐢 when run in shell startup
tea --magic
adds about 100ms of extra latency to my shell startup, which is a lot to me c:
❯ hyperfine --warmup=3 "~/.tea/tea.xyz/v0.21.0/bin/tea --magic"
Benchmark 1: ~/.tea/tea.xyz/v0.21.0/bin/tea --magic
Time (mean ± σ): 157.7 ms ± 60.6 ms [User: 97.5 ms, System: 22.9 ms]
Range (min … max): 103.6 ms … 345.7 ms 25 runs
If I may give my 2¢, while I’m as big a Deno lover as the next guy it’s just not suitable for the sub-100ms startup times maniacs like myself crave for our terminal.
As a best-case scenario I measured the fastest possible time the magic could run
#!/usr/bin/env deno run
// magic.ts
console.log(`add-zsh-hook -Uz chpwd() {
if [ "\${TEA_MAGIC:-}" != 0 -a -x "/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin"/tea ]; then
source <("/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin"/tea +tea.xyz/magic -Esk --chaste env)
fi
}
# if the user put tea in eg. /usr/local/bin then don’t pollute their PATH
if ! tea --prefix 2>&1 >/dev/null; then
export PATH="/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin:$PATH"
fi
function command_not_found_handler {
if [ "\${TEA_MAGIC:-}" != 0 -a -x "/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin"/tea ]; then
"/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin"/tea -- $*
fi
}
`)
❯ hyperfine --warmup=3 ./magic.ts
Benchmark 1: ./magic.ts
Time (mean ± σ): 63.6 ms ± 7.6 ms [User: 37.2 ms, System: 17.8 ms]
Range (min … max): 57.3 ms … 88.6 ms 40 runs
compared to something like
package main
// magic.go
import "fmt"
func main() {
fmt.Println(
`add-zsh-hook -Uz chpwd() {
if [ "${TEA_MAGIC:-}" != 0 -a -x "/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin"/tea ]; then
source <("/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin"/tea +tea.xyz/magic -Esk --chaste env)
fi
}
# if the user put tea in eg. /usr/local/bin then don’t pollute their PATH
if ! tea --prefix 2>&1 >/dev/null; then
export PATH="/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin:$PATH" fi
function command_not_found_handler {
if [ "${TEA_MAGIC:-}" != 0 -a -x "/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin"/tea ]; then
"/Users/m0c0j7y/.tea/tea.xyz/v0.21.0/bin"/tea -- $*
fi
}`)
}
❯ hyperfine --warmup=3 ./magic
Benchmark 1: ./magic
Time (mean ± σ): 10.5 ms ± 9.2 ms [User: 1.5 ms, System: 3.0 ms]
Range (min … max): 0.0 ms … 36.9 ms 160 runs
Warning: Command took less than 5 ms to complete. Note that the results might be inaccurate because hyperfine can not calibrate the shell startup time much more precise than this limit. You can try to use the `-N`/`--shell=none` option to disable the shell completely.
The difference is even starker when run “e2e”

About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 1
- Comments: 21 (21 by maintainers)
Yeah 100ms is not acceptable for sure. Once we are 1.0.0 I plan to rewrite in Rust. But until then deno is much faster for dev.
Having said this, I’m surprised it is this much since
--magic
is a pretty hot path.I can see a few quick fixes, make
tea
a shell script that handles some of the options fast and then delegates the rest. Unfortunately shell magic involves calling tea so that is everycd
. Possibly we could cache that though.I’ll give it some thought. Thanks for the (very) detailed report!
The last one would be what I’d expect to be the most taxing but it isn’t.
Thoughts
--magic
(which is just a longconsole.log
) should really not take so longThat’s good news. If we can get startup down 50% - 80% then a rewrite in rust may never be necessary.
sure thing. I’ll set something up.
pure rust is a slight improvement:
Deno recently merged a PR to allow for snapshotting of ES modules (https://github.com/denoland/deno/pull/17460). When/if this gets extended for use in
deno compile
, we should see a pretty hefty perf improvement. In my (rather limited) understanding, it essentially converts typescript from a JIT language to a compiled language by doing the compile step ahead of time.While this obviously will not “solve” the problem of typescript being slower than rust, it should alleviate a lot of the pain for users in the mean-time.