Skip to content

Commit

Permalink
Increase speed a thousand fold by caching
Browse files Browse the repository at this point in the history
On my little laptop, the current script output rate is about 1.8 KBytes/s, which is nearly equal to the speed of the VT340's serial port (19.2 kbps). That is plenty fast for my VT340+ as the graphics processor is (probably) the bottleneck. 

However, the script could be made _much_ faster by caching the calculations in an array. [Here is a version](https://github.com/hackerb9/vt340test/blob/main/jerch/endless.sh) that increases the speed from 1.8 KBps to 1.8 MBps, as measured by `./endless.sh | pv -brat > /dev/null`.

Code is included, but commented out, that would increase the speed to 88 MBps by caching into a string instead of an array.

If desired, startup time could be shrunk. It takes about three seconds to create the cache during which the output rate is the same as before (1.8 KBps), but that be done more swiftly by moving the `for` loop within bc instead of forking bc 600 times.
  • Loading branch information
hackerb9 authored Dec 16, 2022
1 parent 4e57b0d commit b1c0286
Showing 1 changed file with 36 additions and 10 deletions.
46 changes: 36 additions & 10 deletions fixture/endless.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,47 @@

# sixel endless mode
# Should print an endless sine curve, abort with Ctrl-C.
# A genuine VT340 terminal updates this continuously.

# Always send ST to end sixel mode when script exits
ST=$'\e\\'
trap 'echo -en "$ST"' EXIT

period=200
amplitude=50

sixels=(@\$ A\$ C\$ G\$ O\$ _\$-)
pi=$(echo "scale=10; 4*a(1)" | bc -l)
run=true
trap run=false INT
sixels=(@$ A$ C$ G$ O$ _\$-)
pi=3.141592653589793238

# Number of samples (m*period) must be divisble by both $period and 6.
declare -i m=1
if ! factor $period 2>&- | cut -d: -f2- | grep -q -w 2; then
m=m*2
fi
if ! factor $period 2>&- | cut -d: -f2- | grep -q -w 3; then
m=m*3
fi

# Start sixels graphics string
echo -ne "\x1bP0;0;0q\"1;1#1;2;100;0;0#1"
y=0
while $run

# Cache the calculations in an array for speed
for (( y=0; y < m*period; y++ ))
do
x=$(echo "x=s(2*${pi}*${y}/${period})*${amplitude}+2*${amplitude}+0.5; scale=0; x/1" | bc -l)
echo -ne "!${x}?${sixels[$((y%6))]}" # 1.8 KBps (uncached)
f[y]=$(echo -ne "!${x}?${sixels[$((y%6))]}") # 1.8 MBps (cached elts)
g+=$(echo -ne "!${x}?${sixels[$((y%6))]}") # 88 MBps (string)
done

while :
do
x=$(echo "s(2*${pi}*${y}/${period})*${amplitude}+2*${amplitude}+0.5" | bc -l)
echo -ne "!${x%%.*}?${sixels[$((y%6))]}"
(( y++ ))
for y in ${!f[@]}; do echo -n "${f[y]}"; done # 1.8 MBps (cached elt)
# echo -n "${f[*]}" # 48 MBps (all elts)
# echo -n "$g" # 88 MBps (string)
done
echo -e "\x1b\\"


# NOTES
#
# Simple way to measure the speed is `./endless.sh | pv >/dev/null`

0 comments on commit b1c0286

Please sign in to comment.