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

271 lines, 138 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 <> {
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=( ${@:2} )
138
139 local len=${#argv[@]}
140 #echo "len=$len"
141 if test $len -eq 0; then
142 echo 'argv required'
143 fi
144
145 local sh=$1
146
147 #exec-sh-count bash T & < <(seq 100 | slow-stream)
148
149 echo "[pid $$] Spawn stream with write delay $write_delay"
150
151 seq 10 | slow-stream $write_delay | "${argv[@]}" &
152 local pid=$!
153
154 echo "pid of background job = $pid"
155 echo 'pstree:'
156 pstree -p $pid
157 echo
158
159 echo "[pid $$] Entering kill loop ($kill_delay secs)"
160
161 while true; do
162 # wait for USR1 to be registered
163 sleep $kill_delay
164
165 kill -s USR1 $pid
166 local status=$?
167
168 echo "[pid $$] kill $pid status: $status"
169 if test $status -ne 0; then
170 break
171 fi
172
173 done
174
175 time wait
176 echo "wait status: $?"
177}
178
179test-ysh-for() {
180 sh-count-slow-trap '' '' exec-ysh-count $YSH_ASAN T
181}
182
183test-ysh-read-error() {
184 ### testing errno!
185
186 set +o errexit
187 $YSH_ASAN -c 'for x in <> { echo $x }' < /tmp
188 echo status=$?
189}
190
191test-read-errors() {
192 set +o errexit
193
194 # Awk prints a warning, but exits 0!
195 awk '{ print }' < /tmp
196 echo status=$?
197 echo
198
199 seq 3 | perl -e 'while (<>) { print "-" . $_ }'
200
201 # Hm perl doesn't report this error!
202 perl -e 'while (<>) { print }' < /tmp
203 echo status=$?
204
205 echo
206
207 python3 -c '
208import sys
209for line in sys.stdin:
210 print(line)
211print("end")
212' < /tmp
213 echo status=$?
214
215
216}
217
218readonly BIG_FILE=_tmp/lines.txt
219
220setup-benchmark() {
221 local n=${1:-1} # how many copies
222 mkdir -p $(dirname $BIG_FILE)
223
224 for i in $(seq $n); do
225 big-stream
226 done > $BIG_FILE
227
228 wc -l $BIG_FILE
229
230 ninja $OSH_OPT $YSH_OPT
231}
232
233setup-test() {
234 ninja $OSH_ASAN $YSH_ASAN
235}
236
237soil-benchmark() {
238 setup-benchmark
239
240 compare-line-count
241}
242
243soil-test() {
244 setup-test
245
246 # dash exits at the first try
247 #sh-count-slow-trap '' '' exec-sh-count dash T
248
249 #sh-count-slow-trap '' '' exec-sh-count bash T
250
251 # Oh interesting, mksh waits until the main loop! Different behavior
252 #sh-count-slow-trap '' '' exec-sh-count mksh T
253
254 #sh-count-slow-trap '' '' exec-sh-count $OSH_ASAN T
255
256 # OSH behaves like bash/zsh, yay
257
258 test-ysh-for
259
260
261 return
262
263 for sh in $YSH_OPT dash bash $OSH_OPT; do
264 sh-count-with-trap $sh
265 echo
266 echo
267 done
268}
269
270"$@"
271