| 1 | #!/usr/bin/env bash | 
| 2 | # | 
| 3 | # Test how long it takes to read many files | 
| 4 |  | 
| 5 | big-stream() { | 
| 6 | cat */*.py | 
| 7 | # Python messes up here! | 
| 8 | #*/*/*.py | 
| 9 | } | 
| 10 |  | 
| 11 | OSH=_bin/cxx-opt/osh | 
| 12 | YSH=_bin/cxx-opt/ysh | 
| 13 |  | 
| 14 | setup() { | 
| 15 | local n=${1:-1}  # how many copies | 
| 16 |  | 
| 17 | for i in $(seq $n); do | 
| 18 | big-stream | 
| 19 | done > $BIG_FILE | 
| 20 |  | 
| 21 | wc -l $BIG_FILE | 
| 22 |  | 
| 23 | ninja $OSH $YSH | 
| 24 | } | 
| 25 |  | 
| 26 | py3-count() { | 
| 27 | echo '=== python3' | 
| 28 |  | 
| 29 | # Buffered I/O is much faster | 
| 30 | python3 -c ' | 
| 31 | import sys | 
| 32 | i = 0 | 
| 33 | for line in sys.stdin: | 
| 34 | i += 1 | 
| 35 | print(i) | 
| 36 | ' | 
| 37 | } | 
| 38 |  | 
| 39 | awk-count() { | 
| 40 | echo '=== awk' | 
| 41 | awk '{ i += 1 } END { print i } ' | 
| 42 | } | 
| 43 |  | 
| 44 | exec-ysh-count() { | 
| 45 | local do_trap=${1:-} | 
| 46 |  | 
| 47 | echo '=== ysh' | 
| 48 |  | 
| 49 | local code=' | 
| 50 | var i = 0 | 
| 51 | for _ in <> { | 
| 52 | setvar i += 1 | 
| 53 | } | 
| 54 | echo $i | 
| 55 | ' | 
| 56 |  | 
| 57 | if test -n "$do_trap"; then | 
| 58 | # Register BEFORE creating pipeline | 
| 59 | #trap usr1-handler USR1 | 
| 60 | code=" | 
| 61 | trap 'echo usr1 in \$\$' USR1 | 
| 62 |  | 
| 63 | $code | 
| 64 | " | 
| 65 | fi | 
| 66 |  | 
| 67 | # New buffered read! | 
| 68 | exec $YSH -c "$code" | 
| 69 | } | 
| 70 |  | 
| 71 | usr1-handler() { | 
| 72 | echo "pid $$ got usr1" | 
| 73 | } | 
| 74 |  | 
| 75 | exec-sh-count() { | 
| 76 | local sh=$1 | 
| 77 | local do_trap=${2:-} | 
| 78 |  | 
| 79 | echo "pid = $$" | 
| 80 |  | 
| 81 | echo === $sh | 
| 82 |  | 
| 83 | local code=' | 
| 84 | i=0 | 
| 85 | while read -r line; do | 
| 86 | i=$(( i + 1 )) | 
| 87 | done | 
| 88 | echo $i | 
| 89 | ' | 
| 90 |  | 
| 91 | if test -n "$do_trap"; then | 
| 92 | # Register BEFORE creating pipeline | 
| 93 | #trap usr1-handler USR1 | 
| 94 | code=" | 
| 95 | trap 'echo usr1 in \$\$' USR1 | 
| 96 |  | 
| 97 | $code | 
| 98 | " | 
| 99 | fi | 
| 100 | #echo "$code" | 
| 101 |  | 
| 102 | # need exec here for trap-demo | 
| 103 | exec $sh -c "$code" | 
| 104 | } | 
| 105 |  | 
| 106 | readonly BIG_FILE=_tmp/lines.txt | 
| 107 |  | 
| 108 | compare() { | 
| 109 |  | 
| 110 | echo '=== wc' | 
| 111 | time wc -l < $BIG_FILE  # warmup | 
| 112 | echo | 
| 113 |  | 
| 114 | time py3-count < $BIG_FILE | 
| 115 | echo | 
| 116 |  | 
| 117 | time awk-count < $BIG_FILE | 
| 118 | echo | 
| 119 |  | 
| 120 | time $0 exec-ysh-count < $BIG_FILE | 
| 121 | echo | 
| 122 |  | 
| 123 | for sh in dash bash $OSH; do | 
| 124 | # need $0 because it exec | 
| 125 | time $0 exec-sh-count $sh < $BIG_FILE | 
| 126 | echo | 
| 127 | done | 
| 128 | } | 
| 129 |  | 
| 130 | sh-count-with-trap() { | 
| 131 | local sh=$1 | 
| 132 |  | 
| 133 | local -a argv | 
| 134 | case $sh in | 
| 135 | *ysh) | 
| 136 | argv=(exec-ysh-count T) | 
| 137 | ;; | 
| 138 | *) | 
| 139 | argv=(exec-sh-count $sh T) | 
| 140 | ;; | 
| 141 | esac | 
| 142 |  | 
| 143 | "${argv[@]}" < $BIG_FILE & | 
| 144 |  | 
| 145 | #$0 sh-count bash T & | 
| 146 | #$0 sh-count dash T & | 
| 147 |  | 
| 148 | local pid=$! | 
| 149 | echo "background = $pid" | 
| 150 | pstree -p $pid | 
| 151 | echo | 
| 152 |  | 
| 153 | #wait | 
| 154 | #echo status=$? | 
| 155 | #return | 
| 156 |  | 
| 157 | while true; do | 
| 158 | # wait for USR1 to be registered | 
| 159 | sleep 0.05 | 
| 160 |  | 
| 161 | kill -s USR1 $pid | 
| 162 | local status=$? | 
| 163 |  | 
| 164 | echo "kill status: $status" | 
| 165 | if test $status -ne 0; then | 
| 166 | break | 
| 167 | fi | 
| 168 |  | 
| 169 | done | 
| 170 |  | 
| 171 | wait | 
| 172 | echo status=$? | 
| 173 | } | 
| 174 |  | 
| 175 | compare-trap() { | 
| 176 | for sh in $YSH dash bash $OSH; do | 
| 177 | sh-count-with-trap $sh | 
| 178 | echo | 
| 179 | echo | 
| 180 | done | 
| 181 | } | 
| 182 |  | 
| 183 | "$@" | 
| 184 |  |