It may be somewhat masochistic, but making a single tiny aspect of my computer unnecessarily, almost stupidly efficient brings a strange joy to my heart. At this moment, the target of that obsession is my status bar. I dream of an age where my status bar updates itself exactly when necessary and never else. To that end, I’m going to write what could be the most efficient date/time printer ever.
I’ll lay out the exact goals here so that we can objectively measure my success.
The end result of this journey will be a GNU C23 program for arbitrarily recent
Linux kernels which periodically formats the current date and time and prints it
as a single line to standard output. It will print a new line immediately after
the current time changes from the user’s perspective (e.g. a minute passes, the
timezone changes, etc.). I18N / L10N are explicit non-goals - I might hardcode
date-time formatting logic for my own locale (effectively en_GB.UTF-8
). Over
time, I will refine this program to take as few system resources as possible –
something we can measure in terms of CPU time and memory consumption.
Each post in this series will cover one or two improvements to the program, with explanations of the technologies used and benchmarks measuring the improvement. For a start, we’ll compare to the classic shell script:
while :; do
date '+%A, %d %b %Y %H:%M'
sleep 60
done
This also shows you the format string I’ll be working with. The output looks like this:
> ./minutiae.sh
Wednesday, 27 Dec 2023 09:51
Wednesday, 27 Dec 2023 09:52
Wednesday, 27 Dec 2023 09:53
Wednesday, 27 Dec 2023 09:54
^C
Let’s see if I can benchmark this. For fairness, I’ll run the script using
dash
rather than bash
– it’s more lightweight and we don’t need any extra
features anyways. Using perf stat
for some overall information:
> perf stat ./minutiae.sh
...
Performance counter stats for './minutiae.sh':
765.46 msec task-clock:u # 0.000 CPUs utilized
0 context-switches:u # 0.000 /sec
0 cpu-migrations:u # 0.000 /sec
39,859 page-faults:u # 52.072 K/sec
207,468,145 cycles:u # 0.271 GHz
141,723,023 instructions:u # 0.68 insn per cycle
30,836,134 branches:u # 40.284 M/sec
2,269,916 branch-misses:u # 7.36% of all branches
17138.888268817 seconds time elapsed
0.481000000 seconds user
0.350438000 seconds sys
This is surprisingly efficient! Over 268 minutes of runtime (not counting time
suspended), less than a second of CPU time was spent. I’m reasonably certain
that this is counting the overhead of all the programs involved: dash
, date
,
and sleep
. But minutiae.sh
is not perfect. Not by a long shot.