Using dwm with dwmblocks? Consider slstatus!
Because it is considerably more efficient. Maybe 10 times in your case.
It can be worthwhile to trade simplicity of shell scripting for efficiency of C.
Besides, you can run shell scripts from slstatus
as well and migrate away from scripts step by step.
1. Setup
First, don’t litter and test in tmpfs:
mkdir /tmp/bench && cd $_
I use my fork of slstatus
, where I have (custom things in bold)
- date
- used+total memory and swap
- CPU load and its average frequency
- network traffic
- MPD status and volume
git clone "https://github.com/ivan-boikov/slstatus"
cd slstatus && make -j && cd -
Compare it to vanilla dwmblocks
trying to match most of slstatus
’s functionality.
Also note that all blocks will run every second as slstatus
does.
git clone "https://github.com/torrinfail/dwmblocks" && cd "dwmblocks"
rm blocks.h && cp blocks.def.h blocks.h
sed -i '4,6d' blocks.h
sed -i '4i{"Mem:", "free -h | awk '\''/^Mem/ { print $3\\"/\\"$2 }'\'' | sed s/i//g", 1, 0},' blocks.h
sed -i '5i{"Swap:", "free -h | awk '\''/^Swap/ { print $3\\"/\\"$2 }'\'' | sed s/i//g", 1, 0},' blocks.h
sed -i '6i{"", "date '\''+%b %d (%a) %I:%M:%S%p'\''", 1, 0},' blocks.h
sed -i '7i{"Freq:", "awk -F \\" \\" '\''{ total += $1; count++ } END { printf \\"%.1f\\", total/count/1e6 }'\'' /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq", 1, 0},' blocks.h
sed -i '8i{"Net:", "/tmp/bench/dwmblocks/sb-nettraf", 1, 0},' blocks.h
wget "https://raw.githubusercontent.com/ivan-boikov/.dotfiles/master/scripts/.local/bin/sb-nettraf"
make -j
There is everything but the CPU use, MPD status and the volume. But it’s fine.
Here, the measurement of network traffic is too complicated for a one-liner; sb-nettraf
is a trimmed version of the original by LukeSmithxyz.
2. Benchmark
Plan: run for 30 seconds using timeout
from GNU core utilities and measure CPU time and a number of syscalls with strace
:
strace -cf -e 'trace=!wait4' timeout 30 <executable path>
Here, -c
or --summary-only
will only count syscalls and CPU time.
With -f
strace
will follow forks - crucial for dwmblocks
who does everything in forks.
Waiting is doing nothing, so ignore wait4
with -e
.
For brevity, only 5 longest syscalls will be shown.
dwmblocks
does everything in scripts and uses popen
to execute them.
According to man popen
, /bin/sh
is used, which can be a symlink to another shell.
So let’s compare three cases
dwmblocks
withbash
as the default shell- same, but with
dash
, a faster POSIX-compliant shell slstatus
Gentoo-specific
I used to manually install app-shells/bash
only, and sh
was, in fact, bash
.
Hence, the first benchmark is to see how big was my mistake.
A proper way is to install app-alternatives/sh
with correct USE flags.
# dwmblocks+bash
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
18.09 0.041899 84 498 execve
14.21 0.032922 3 10232 mmap
12.50 0.028963 1 15667 2325 newfstatat
7.78 0.018013 3 5189 186 openat
7.18 0.016628 53 311 clone
------ ----------- ----------- --------- --------- ----------------
100.00 0.231649 2 89537 4604 total
# dwmblocks+dash
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
16.13 0.017563 2 6145 mmap
14.77 0.016081 31 514 execve
10.15 0.011053 3 3564 192 openat
9.61 0.010466 1 6956 1376 newfstatat
6.78 0.007387 1 4712 read
------ ----------- ----------- --------- --------- ----------------
100.00 0.108903 2 47135 3022 total
# slstatus
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
45.94 0.004753 12 370 read
27.08 0.002802 8 343 30 openat
7.85 0.000812 2 343 newfstatat
6.79 0.000703 2 316 close
4.39 0.000454 5 90 write
------ ----------- ----------- --------- --------- ----------------
100.00 0.010347 5 1768 108 total
3. Analysis
dwmblocks+bash |
dwmblocks+dash |
slstatus |
|
---|---|---|---|
CPU time, norm | 22.4 | 10.5 | 1.0 |
Syscalls, norm | 50.6 | 26.7 | 1.0 |
Mean CPU load, % | 0.772 | 0.363 | 0.034 |
So, I was using about 1% of my CPU just for a statusbar and fixing my blunder improved the efficiency 22 times.
The thing that instigated me to do all this was powertop
claiming that with just dwmblocks+bash
in the background, my laptop’s CPU woke up about 600 times per second, largely due to tick_sched_timer
.
According to superuser it means the CPU often switches contexts.
A rough measurement with
cat /proc/$(pidof dwmblocks)/status
showed that dwmblocks
with bash
or dash
caused around 15 switches/second, while slstatus
– just 1 switch/second.
Now, the CPU wakes up 150 times per second.