refactor(config parsing): change from if/elif chain to precalculated hash table with switch case and added caching of keysyms

this refactor marginally speeds up config parsing by targetting the 2
biggest bottlenecks, namely iterating over keysyms every time and using
extremely long if/elif chains.

benchmarking each command with 1000 runs:

/home/duck/mango/build/mango -p (the code in this PR)
  Average: 4.88 ms  (std dev: 1.08 ms)

mango -p
  Average: 5.31 ms  (std dev: 1.01 ms)

about 1.09x faster

this PR does somewhat make it harder to add new functions/options in
that they need to be added to both parse_config.h in the switch case and
in the appropriate .gperf file.

that being said the improvements would get more noticeable as mango adds
more options to its configuration.

as for readability, I believe a switch case is more readable.
This commit is contained in:
DuckTapeMan35 2026-04-08 22:01:13 +01:00
parent e83a9dff82
commit 5585128172
4 changed files with 2361 additions and 1353 deletions

View file

@ -39,7 +39,7 @@ libinput_dep = dependency('libinput',version: '>=1.27.1')
libwayland_client_dep = dependency('wayland-client')
pcre2_dep = dependency('libpcre2-8')
libscenefx_dep = dependency('scenefx-0.4',version: '>=0.4.1')
gperf = find_program('gperf', required : true)
# 获取版本信息
git = find_program('git', required : false)
@ -94,11 +94,28 @@ if get_option('asan')
link_args += '-fsanitize=address'
endif
# Generate hash files
func_names_hash = custom_target(
'func_names_hash',
input: 'src/config/func_names.gperf',
output: 'func_names_hash.h',
command: [gperf, '@INPUT@', '--output-file', '@OUTPUT@']
)
option_names_hash = custom_target(
'option_names_hash',
input: 'src/config/option_names.gperf',
output: 'option_names_hash.h',
command: [gperf, '@INPUT@', '--output-file', '@OUTPUT@']
)
executable('mango',
'src/mango.c',
'src/common/util.c',
'src/ext-protocol/wlr_ext_workspace_v1.c',
wayland_sources,
func_names_hash,
option_names_hash,
dependencies : [
libm,
xcb,