Interactive shells: a comparison


#1

Hello community :slight_smile:

With the new 5.0 version of bash just out I thought it was a good time to examine the speed and resource usage of the various shells that are available for interactive use.

To test the speed I am using a simple iterative loop:

for i in $(seq 1 1000000); do [ 1 = 1 ]; done

Each test was run three times with the best result selected.

And for resource usage I have trusty old ps_mem.py, which is available in [Community]:

https://www.archlinux.org/packages/community/any/ps_mem/

The shells are under test are bash (obviously), zsh (ArchLabs’ default interactive shell), mksh (which is used as the default shell in the Android operating system), dash (Debian’s default /bin/sh replacement, optimised for speed at the expense of fancy features), ash (the Almquist shell variant provided by busybox) and finally AT&T’s venerable ksh93 (this used to cost quite a lot of money before it was open-sourced).

Without further ado, here are the results (in alphabetical order)…

Busybox ash:

0m01.86s real     0m01.57s user     0m00.31s system
552.0 KiB +  44.5 KiB = 596.5 KiB       busybox

Bash:

0m03.31s real     0m03.24s user     0m00.08s system
  2.4 MiB +  79.5 KiB =   2.5 MiB       bash

Dash:

0m01.10s real     0m01.07s user     0m00.04s system
196.0 KiB +  29.5 KiB = 225.5 KiB       dash

Ksh93:

0m00.84s real     0m00.82s user     0m00.03s system
  1.7 MiB +  74.5 KiB =   1.7 MiB       ksh93

Mksh:

0m01.98s real     0m01.97s user     0m00.03s system
664.0 KiB + 101.5 KiB = 765.5 KiB       mksh

Zsh:

0m04.88s real     0m04.13s user     0m00.76s system
  1.9 MiB +  93.5 KiB =   2.0 MiB       zsh

I did these tests a while ago with older versions of bash & zsh, bash has sped up slighly (which surprised me) and zsh has become slightly slower (more features added, perhaps?).

Although dash & ksh93 look very tempting, I find dash too limited in respect of features (no here strings or tab-completion, which is a real deal-breaker for me) and I have it on good authority (from the people currently working on the next version) that ksh93 has many bugs due to it’s advanced decrepitude.

For me personally, I like mksh best for it’s mix of speed, low memory usage and functionality — it doesn’t do associative arrays (AFAICT) but I’ve never used those interactively so that’s not really a problem. It’s status as Android’s default shell also means lots of users and “eyes on the code”, which should reduce bugs & vulnerabilities, at least theoretically.

To change the default shell for your user, run

chsh -s $(which $shell)

^ Replace $shell with the name of the desired shell.

Thanks for reading!


#2

Wow, that s some great work @Head_on_a_Stick .

Thx for sharing.

Edit: Must say that there are some surprises.


#3

Interesting. I like it. Thanks @Head_on_a_Stick!!


#4

Sweet read


#5

Using brace expansion {1..1000000} rather than a subshell $(seq 1 1000000) where supported gains some time back… ~18% or ~0.4s on my system.

% time zsh -c 'for i in $(seq 1 1000000); do [ 1 = 1 ]; done'
zsh -c 'for i in $(seq 1 1000000); do [ 1 = 1 ]; done'  1.72s user 0.48s system 99% cpu 2.203 total

# vs

% time zsh -c 'for i in {1..1000000}; do [ 1 = 1 ]; done'
zsh -c 'for i in {1..1000000}; do [ 1 = 1 ]; done'  1.48s user 0.35s system 99% cpu 1.835 total

However mksh still stomps it

% time mksh -c 'for i in $(seq 1 1000000); do [ 1 = 1 ]; done'
mksh -c 'for i in $(seq 1 1000000); do [ 1 = 1 ]; done'  1.06s user 0.01s system 100% cpu 1.064 total

Very cool comparison overall and thanks for sharing HoaS.

(you’ll pry zsh’s completion from my cold dead hands :P)


#6

Yes but that’s cheating :slight_smile:

In all seriousness though, tricks like brace expansion are very good reasons to prefer zsh & bash over simpler alternatives like ash & mksh; I just don’t use brace expansion much in interactive terminals, hence my preference for mksh.

Nice system btw.

:grin: