-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathutil.bash
185 lines (160 loc) · 5.7 KB
/
util.bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
aliasing () {
# $1 cond
# $2 alias name
# $3 optional 2nd alias (otherwise, no$2)
local -i cond=$1
((cond==0)) &&
BASH_ALIASES[$2]= BASH_ALIASES[${3-no$2}]='#' ||
BASH_ALIASES[$2]='#' BASH_ALIASES[${3-no$2}]=
((cond==0))
}
dumpstats() {
# see tests in https://gist.github.com/izabera/3d1e5dfabbe80b3f5f2e50ec6f56eadb
END=${EPOCHREALTIME/.}
title () { printf '\e[38;5;201m==== %s ====\e[m\n' "$@"; }
info () {
local -A colours=([true]=46 [false]=196)
printf '%s: \e[38;5;%sm%s\e[m\n' "$1" "${colours[${2:-0}]-33}" "$2"
}
note () { echo "note: $*"; }
title 'frame stats'
info 'final resolution' "${cols}x$((rows*2))"
info 'fps target' "$FPS"
info 'renderers' "${NTHR-1}"
tf=(false true)
[[ $UNBUFFERED ]]
info 'unbuffered' "${tf[!$?]}"
[[ $MINIMAP ]]
info 'minimap' "${tf[!$?]}"
info 'terminated after frame' "$FRAME"
if ((BENCHMARK)); then
info 'time per frame' "$(((END-START)/FRAME))µs"
else
info 'skipped frames' "$TOTALSKIPPED ($((TOTALSKIPPED*100/FRAME))%)"
fi
if ((${#frametimes[@]})); then
# basic counting sort
sorted=() sum=0 counted=()
for n in "${!frametimes[@]}"; do counted[n]=${frametimes[$n]}; done
for n in "${!counted[@]}"; do
for ((i=0;i<counted[n];i++)) do
sorted+=("$n")
((sum+=n))
done
done
min=${sorted[0]} max=${sorted[-1]}
framecount=${#sorted[@]}
mean=$((sum/framecount))
sum=0 sqdiffs=()
for i in "${!sorted[@]}"; do
((sum+=(sqdiffs[i]=(sorted[i]-mean)**2)))
done
variance=$((sum/framecount))
# newton's method
x=$((variance/2))
while ((x)); do
((prev=x,x=(x+variance/x)/2,x==prev)) && break
done
stddev=$x
info 'fastest frame' "$min"µs
info 'slowest frame' "$max"µs
info 'average frame' "$mean"µs
info '95th %ile' "${sorted[framecount*95/100]}"µs
info 'std dev' "$stddev"µs
info 'your bash can render' "$((1000000/max))-$((1000000/mean))fps"
note 'times are collected after drawing to the terminal,' \
'but they do not accurately account for any slowness induced by it'
fi
title 'shell info'
info 'bash path' "$BASH"
info 'bash version' "$BASH_VERSION"
info 'preload' "${LD_PRELOAD:-<empty>}"
affinity=$(taskset -pc "$$" 2>/dev/null)
affinity=${affinity##*: }
info 'cpu affinity' "${affinity:-unknown}"
# sometimes useful but they don't really need to be accessed at runtime
# {
# comment=$(readelf -p .comment "$BASH")
# cmdline=$(readelf -p .GCC.command.line "$BASH")
# } 2>/dev/null
# info '.comment' "${comment:-empty}"
# info '.GCC.command.line' "${cmdline:-empty}"
title 'terminal info'
info '$TERM' "$TERM"
info '$COLORTERM' "$COLORTERM"
if [[ $DISPLAY ]] && type xprop &>/dev/null; then
IFS=' ' read -r _ _ _ _ self _ < <(xprop -root _NET_ACTIVE_WINDOW)
IFS='"' read -r _ _ _ class _ < <(xprop -id "$self" WM_CLASS)
else
class=unknown
fi
info 'wm class' "$class"
colours=(256 truecolor)
info colours "${colours[truecolor]}"
info 'kitty keyboard proto support' "${tf[kitty]}"
info 'synchronised output support' "${tf[sync]}"
# r | g | b | rdx | gdx | bdx
# ------------+-----------+-----------+-----+-----+----
# max | 0->max | 0 | 0 | 1 | 0
# max->0 | max | 0 | -1 | 0 | 0
# 0 | max | 0->max | 0 | 0 | 1
# 0 | max->0 | max | 0 | -1 | 0
# 0->max | 0 | max | 1 | 0 | 0
# max | 0 | max->0 | 0 | 0 | -1
# walk around an rgb cube on the edges that don't include black or white
walkcube () {
local max=$(($1-1)) fmt=$2
local rdx=4 gdx=2 bdx=0
local r=max g=0 b=0
local i j
for (( i = 0; i < 6; i++ )) do
for (( j = 0; j < max; j++ )) do
printf -v 'hues[i*max+j]' "$fmt" \
"$(( r += (rdx%6==2)-(rdx%6==5) ))" \
"$(( g += (gdx%6==2)-(gdx%6==5) ))" \
"$(( b += (bdx%6==2)-(bdx%6==5) ))"
done
(( rdx = (rdx+1) % 6, gdx = (gdx+1) % 6, bdx = (bdx+1) % 6 ))
done
}
declare -ai hues
walkcube 6 '16 + %d*6*6 + %d*6 + %d'
printf '256 colour test: '
printf '\e[38;5;%s;48;5;%sm▌' "${hues[@]}"
printf '\e[m\n'
unset hues
walkcube 256 '%d;%d;%d'
h=${#hues[@]}
for (( i = 0; i < h && h>cols; i++ )) do
(( i % (h/cols) )) && unset 'hues[i]'
done
printf '24bit colour test: '
printf '\e[38;2;%s;48;2;%sm▌' "${hues[@]}"
printf '\e[m\n'
((truecolor)) || note 'if the 24bit colour test looks ok, set COLORTERM=truecolor'
}
drawmsgs () {
set -- "${msgs[@]:(${#msgs[@]}>5?-5:0):5}"
printf '\e[m\e[%s;2H' "$((rows+2-$#))"
printf "%.$((cols+5))s\r\e[B\e[C" "$@"
}
declare -A infos
drawinfo () {
((${#infos[@]}))||return
printf '\e[1;1H\e[m'
printf '%s=%s\t' "${infos[@]@k}"
}
drawborder () {
local i
printf '\e[H'
printf '+%s+\e[K\r\e[B' "${hspaces// /-}"
for ((i=1;i<=rows;i++)) do
printf '|\e[%sC|%d\e[K\r\e[B' "$cols" "$i"
done
printf '+%s+\e[K\r\e[B' "${hspaces// /-}"
}
infos=()
msg= msgs=()
error() { printf -v 'msgs[msg++]' '\e[31m%(%T)T [ERROR]: %s\e[m' -1 "$1"; }
warn () { printf -v 'msgs[msg++]' '\e[33m%(%T)T [WARNING]: %s\e[m' -1 "$1"; }
info () { printf -v 'msgs[msg++]' '\e[34m%(%T)T [INFO]: %s\e[m' -1 "$1"; }