Interesting parallels in this work to Tanenbaum's "RPC Considered Harmful"†; in both cases, you've got an abstraction that papers over a huge amount of complexity, and it ends up burning you because a lot of that complexity turns out to be pretty important and the abstraction has cost you control over it.
Whenever you need better performance and reliability, identify an abstraction beloved of CS professors, and bypass it.
When I last checked, libtorrent was utterly failing to use O_DIRECT semantics. I started making a patch, but there are several places that do file ops, and the main one was more complicated than I could afford to dive into at the time.
So... don't bypass abstractions, unless you actually have time to do a better job, no?
We have abstractions for a reason. We have lower-level primitives for a reason. Understanding the differences, reasoning about all trade-off angles, and making the right choice in each project is a majority of the software engineering job.
> So... don't bypass abstractions, unless you actually have time to do a better job, no?
And unless there's a clear benefit to it. If you haven't identified the abstraction as a significant bottleneck, then is it really worthwhile to go through the trouble of bypassing it?
The problem is that people like to carve out territories in their data architecture before they have become subject matter experts. Once you split two things it's so difficult to add certain kinds of features that most people just give up and deal with higher fanout.
What you often get is the sum being less than the whole of its parts, and trying to offset that by achieving greater 'parts' through coherence and conceptual integrity in isolation. There is such a thing as 'Coherent but wrong'.
† https://www.cs.vu.nl/~ast/Publications/Papers/euteco-1988.pd...