Single-threading for simplicity


Aside for when implemented correctly and when really needed, multi-threading is often a go to for lazy or amateur developers with an uneducated perception that it would boost performance and make the program run faster.

There was a guy who used to ask me to review his code, nothing fancy, just some stuff he wrote to practice programming. Every code base he sent for review had for some reason the same boiler plate for “multi-threading” which I did not even bother to see if it was at least done “properly” as I always rolled my eyes when I see the mess. One project literally was bound to REST rate limits, but he still bombarded the API with thousands of requests each sent in its own thread, because he genuinely believed that it was helping.

Spawning threads is effortless, synchronizing them is difficult. You will have to worry about race conditions, dead locks, while maintenance and debugging cost increases, and turn the project harder to test and conceptualize. Not a fun time, threading should be at the bottom of the list of optimization routes. In fact, this could hurt performance, if multiple threads interact with a shared object, they’ll block each other, effectively rendering them useless. Additionally, threaded programs are more prone to cache misses, due to cache invalidation after a context switch, trashing out hardware level optimization years of engineering tried to squeeze out.

I am all for simplicity, so single-threading when possible is welcomed. But first, we need to know when threads are commonly used, in which I can think of two situations: waiting for I/O or offloading heavy operations where blocking the main thread for a period of time is not an option.

If your threads do nothing but wait for something to happen and act upon it, you’ll be better off relying on an event loop. Consider libevent or write your own. Your target operating system should offer methods for I/O multiplexing, non-blocking calls and asynchronous I/O, so take advantage of those as well. For the other case where the task is indeed CPU-bound, I honestly have no problem with using threads here.

Keep it simple, your initial solution should not involve more threads. Avoid this unwanted complexity, and give it some thoughts on how to approach it when you’re out of choice.

Articles from blogs I read

Generated by openring
  • Silicon designers are bad at designing secure hardware. Embarrassingly so, sometimes. This means that low-level cryptography, as well as code which directly handles key material, often needs to be written in a particularly delicate style called “constant-ti…

    via mcyoung
  • A video call I had with Sam Smith—creator of the Serenum operating system—about fundamental concepts in operating system design pertaining to user-space applications and the desktop environment.

    via Digital Grove
  • I got a new keyboard recently. I used to use a Unicomp Classic keyboard, however it slowly degraded and broke over time. I originally got the keyboard for ~$80, however Unicomp has now hiked the price of their keyboards to almost $200! Needless to say, but I…

    via Bryce Vandegrift's Website