Make the settings screen redraw 50x faster
Arrow-key navigation took 435 ms per keypress, which reads as the whole console reloading on every press - because it effectively was. The cost was forks: each frame ran a command substitution per label for the value, the translation and the rendered state, 54 subshells for eighteen rows. The frame is now assembled in memory and written once. Translations, the split specs and the terminfo clear string are resolved before the loop; values are re-read only after something actually changes, not on cursor movement. Helpers on that path assign to a variable instead of printing, since printing is what forced the substitution. Measured on the same machine: 435 ms -> 7.5 ms per keypress.
This commit is contained in:
1 parent
c308b7e286
commit
2fa830284e
4 files changed
+111
-43
No files matched your search
@@ -75,6 +75,27 @@ cau_msg() {
|
||||
cau_msg_in "$(cau_ui_locale)" "$@"
|
||||
}
|
||||
|
||||
# cau_msg_into <locale> <msgid>
|
||||
# Plain lookup with the result in CAU_MSG_RESULT and no printf formatting.
|
||||
# For callers that redraw many labels per keypress, where wrapping cau_msg in a
|
||||
# command substitution would cost a fork per label.
|
||||
CAU_MSG_RESULT=''
|
||||
|
||||
cau_msg_into() {
|
||||
local locale="$1" msgid="$2" cachekey
|
||||
cachekey="${locale}"$'\x1f'"${msgid}"
|
||||
|
||||
if [[ -n ${CAU_MSG_CACHE[$cachekey]+set} ]]; then
|
||||
CAU_MSG_RESULT="${CAU_MSG_CACHE[$cachekey]}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
CAU_MSG_RESULT="$(LC_ALL="$locale" LANGUAGE="${locale%%.*}" gettext -- "$msgid" 2>/dev/null)"
|
||||
[[ -n $CAU_MSG_RESULT ]] || CAU_MSG_RESULT="$msgid"
|
||||
CAU_MSG_CACHE[$cachekey]="$CAU_MSG_RESULT"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Translations are memoized. Every gettext lookup is a fork, and the settings
|
||||
# screen redraws forty-odd labels per keypress; without this the redraw takes
|
||||
# long enough that a keystroke arriving during it is lost when the terminal
|
||||
|
||||
Reference in new issue
Block a user