| 1 | #!/usr/bin/env bash
 | 
| 2 | #
 | 
| 3 | # Benchmarks for small shell snippets.
 | 
| 4 | #
 | 
| 5 | # Usage:
 | 
| 6 | #   ./micro.sh <function name>
 | 
| 7 | #
 | 
| 8 | # TODO: Publish and HTML report with every release.
 | 
| 9 | 
 | 
| 10 | set -o nounset
 | 
| 11 | set -o pipefail
 | 
| 12 | set -o errexit
 | 
| 13 | 
 | 
| 14 | # OSH:  583 ms
 | 
| 15 | # bash: 40 ms
 | 
| 16 | # ~10 x
 | 
| 17 | assign-loop() {
 | 
| 18 |   time for i in $(seq 10000); do
 | 
| 19 |     echo x
 | 
| 20 |   done | wc -l
 | 
| 21 | }
 | 
| 22 | 
 | 
| 23 | # OSH: 176 ms
 | 
| 24 | # bash: 2 ms!
 | 
| 25 | # This is probably mostly because printf is external!
 | 
| 26 | # ~80x
 | 
| 27 | printf-loop() {
 | 
| 28 |   time seq 100 | while read line; do
 | 
| 29 |     printf '%s\n' "$line"
 | 
| 30 |   done | wc -l
 | 
| 31 | }
 | 
| 32 | 
 | 
| 33 | # This microbenchmark justifies the parse_cache member in
 | 
| 34 | # osh/builtin_printf.py.
 | 
| 35 | #
 | 
| 36 | # With the cache, it runs in ~150 ms.
 | 
| 37 | # Without, it runs in ~230 ms.
 | 
| 38 | 
 | 
| 39 | printf-loop-complex() {
 | 
| 40 |   time seq 1000 | while read line; do
 | 
| 41 |     printf 'hello \t %s \t %q\n' "$line" 'x y'
 | 
| 42 |   done | wc -l
 | 
| 43 | }
 | 
| 44 | 
 | 
| 45 | "$@"
 |