OILS / benchmarks / io / read-lines.sh View on Github | oilshell.org

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