From b1c0286f66adfb3747f9ba9e07aa85e583726650 Mon Sep 17 00:00:00 2001 From: hackerb9 Date: Thu, 15 Dec 2022 17:03:58 -0800 Subject: [PATCH] Increase speed a thousand fold by caching 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. --- fixture/endless.sh | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/fixture/endless.sh b/fixture/endless.sh index a03c049..6a8f09c 100755 --- a/fixture/endless.sh +++ b/fixture/endless.sh @@ -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`