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

282 lines, 140 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
21# TODO: Add to benchmarks2, which uses the oils-for-unix
22OSH_OPT=_bin/cxx-opt/osh
23YSH_OPT=_bin/cxx-opt/ysh
24
25OSH_ASAN=_bin/cxx-asan/osh
26YSH_ASAN=_bin/cxx-asan/ysh
27
28py3-count() {
29 echo '=== python3'
30
31 # Buffered I/O is much faster
32 python3 -c '
33import sys
34i = 0
35for line in sys.stdin:
36 i += 1
37print(i)
38'
39}
40
41awk-count() {
42 echo '=== awk'
43 awk '{ i += 1 } END { print i } '
44}
45
46exec-ysh-count() {
47 local ysh=$1
48 local do_trap=${2:-}
49
50 echo '=== ysh'
51
52 local code='
53var i = 0
54for _ in (io.stdin) {
55 setvar i += 1
56}
57echo $i
58'
59
60 if test -n "$do_trap"; then
61 # Register BEFORE creating pipeline
62 #trap usr1-handler USR1
63 code="
64trap 'echo \[pid \$\$\] usr1' USR1
65trap 'echo \[pid \$\$\] exit with status \$?' EXIT
66echo \"hi from YSH pid \$\$\"
67
68$code
69"
70 fi
71
72 # New buffered read!
73 exec $ysh -c "$code"
74}
75
76usr1-handler() {
77 echo "pid $$ got usr1"
78}
79
80exec-sh-count() {
81 local sh=$1
82 local do_trap=${2:-}
83
84 echo "shell pid = $$"
85
86 echo === $sh
87
88 local code='
89i=0
90while read -r line; do
91 i=$(( i + 1 ))
92done
93echo $i
94'
95
96 if test -n "$do_trap"; then
97 # Register BEFORE creating pipeline
98 #trap usr1-handler USR1
99 code="
100trap 'echo \[pid \$\$\] usr1' USR1
101trap 'echo \[pid \$\$\] exit with status \$?' EXIT
102echo \"hi from $sh pid \$\$\"
103
104$code
105"
106 fi
107 #echo "$code"
108
109 # need exec here for trap-demo
110 exec $sh -c "$code"
111}
112
113compare-line-count() {
114 echo '=== wc'
115 time wc -l < $BIG_FILE # warmup
116 echo
117
118 time py3-count < $BIG_FILE
119 echo
120
121 time awk-count < $BIG_FILE
122 echo
123
124 time $0 exec-ysh-count $YSH_OPT < $BIG_FILE
125 echo
126
127 for sh in dash bash $OSH_OPT; do
128 # need $0 because it exec
129 time $0 exec-sh-count $sh < $BIG_FILE
130 echo
131 done
132}
133
134sh-count-slow-trap() {
135 local write_delay=${1:-0.20}
136 local kill_delay=${2:-0.07}
137 local -a argv=( ${@:3} )
138
139 local len=${#argv[@]}
140 #echo "len=$len"
141
142 if test $len -eq 0; then
143 echo 'argv required'
144 fi
145 echo "argv: ${argv[@]}"
146
147 local sh=$1
148
149 #exec-sh-count bash T & < <(seq 100 | slow-stream)
150
151 echo "[pid $$] Spawn stream with write delay $write_delay"
152
153 seq 10 | slow-stream $write_delay | "${argv[@]}" &
154 local pid=$!
155
156 echo "pid of background job = $pid"
157 echo 'pstree:'
158 pstree -p $pid
159 echo
160
161 echo "[pid $$] Entering kill loop ($kill_delay secs)"
162
163 while true; do
164 # wait for USR1 to be registered
165 sleep $kill_delay
166
167 kill -s USR1 $pid
168 local status=$?
169
170 echo "[pid $$] kill $pid status: $status"
171 if test $status -ne 0; then
172 break
173 fi
174
175 done
176
177 time wait
178 echo "wait status: $?"
179}
180
181test-ysh-for() {
182 sh-count-slow-trap '' '' exec-ysh-count $YSH_ASAN T
183 #sh-count-slow-trap '' '' exec-ysh-count bin/ysh T
184
185 #sh-count-slow-trap 2.0 0.7 exec-ysh-count bin/ysh T
186
187 #sh-count-slow-trap 2.0 0.7 exec-ysh-count $YSH_ASAN T
188}
189
190test-ysh-read-error() {
191 ### testing errno!
192
193 set +o errexit
194 $YSH_ASAN -c 'for x in (io.stdin) { echo $x }' < /tmp
195 echo status=$?
196}
197
198test-read-errors() {
199 set +o errexit
200
201 # Awk prints a warning, but exits 0!
202 awk '{ print }' < /tmp
203 echo status=$?
204 echo
205
206 seq 3 | perl -e 'while (<>) { print "-" . $_ }'
207
208 # Hm perl doesn't report this error!
209 perl -e 'while (<>) { print }' < /tmp
210 echo status=$?
211
212 echo
213
214 python3 -c '
215import sys
216for line in sys.stdin:
217 print(line)
218print("end")
219' < /tmp
220 echo status=$?
221
222
223}
224
225readonly BIG_FILE=_tmp/lines.txt
226
227setup-benchmark() {
228 local n=${1:-1} # how many copies
229 mkdir -p $(dirname $BIG_FILE)
230
231 for i in $(seq $n); do
232 big-stream
233 done > $BIG_FILE
234
235 wc -l $BIG_FILE
236
237 ninja $OSH_OPT $YSH_OPT
238}
239
240setup-test() {
241 ninja $OSH_ASAN $YSH_ASAN
242}
243
244# TODO:
245# - Soil should run tests
246# - Soil should run benchmarks
247
248soil-benchmark() {
249 setup-benchmark
250
251 compare-line-count
252}
253
254soil-test() {
255 setup-test
256
257 # dash exits at the first try
258 #sh-count-slow-trap '' '' exec-sh-count dash T
259
260 #sh-count-slow-trap '' '' exec-sh-count bash T
261
262 # Oh interesting, mksh waits until the main loop! Different behavior
263 #sh-count-slow-trap '' '' exec-sh-count mksh T
264
265 sh-count-slow-trap '' '' exec-sh-count $OSH_ASAN T
266
267 # OSH behaves like bash/zsh, yay
268
269 test-ysh-for
270
271
272 return
273
274 for sh in $YSH_OPT dash bash $OSH_OPT; do
275 sh-count-with-trap $sh
276 echo
277 echo
278 done
279}
280
281"$@"
282