It's not always a business decision. GNOME, KDE, X, systemd, dbus... The list goes on and on. None of this software is business derived.
Honestly, an engineer that cares about the performance of their code has several options available:
- design the project first, then code later.
- design the code for the architecture (arrays of objects vs. objects of arrays).
- use tools that can optimize out inefficiencies.
- hand optimize after writing a functional slice.
- document the APIs and interfaces to explain the performance expected as part of their contract.
Unfortunately, it seems as though we've gotten into a bit of a rut when it comes to this -- we rely on the awful tooling we have to optimize the code we write (yes, LLVM and friends are light years better at this than GCC et. al., but it's still not enough), we never document performance characteristics of the libraries and APIs we create, and we (at least in the OSS world) almost never design our projects to the level of detail necessary to fully understand it.
Honestly, I'm not sure how we can solve these problems if the engineers have a lack of discipline. It's a hobby, after all, right? We do this in our spare time, and nobody wants to write designs or document because that's the least interesting part of coding. See also GTK's autodocs, which for /years/ lay around as nothing more than a simple enumeration of which functions were in the libraries. Even in self documenting languages we fail at this (I'm looking at you, Common Lisp).
Optimizing afterward is a simple, if lazy, way out but post-facto optimization can only take you so far if the design is simply broken.
Since we never document or design, the problem ends up falling to our tooling. Things like oprofile and so on work, but are usually so coarse grained that digging through the code to instrument it effectively becomes a grind nobody wants to do.
Maybe we need companies to develop free and open tooling for understanding the performance characteristics of the code we write. After all, the "modern" tooling we use for languages like C and C++ hasn't changed since the 80s, and it's often actually hostile to the end user, which just makes the job harder. Even our linkers often fail to do their jobs of optimizing out useless dependencies or symbols unless we explicitly tell them to do so.
Ultimately, the blame lies with us, the engineers who work on this code. New engineers joining our projects need to understand the code itself through and through. Our projects have become so large that without documentation no-one can make a clear, clean decision on what should or shouldn't be written anymore.
What I want to see is tooling that can semantically understand the code I write, and give me characterizations of the function calls I make as I write them. When I need to examine source to better understand it, I want tooling that tells me how often the functions are called, where they are called, and how. Raw text is great for writing prose, but we're not writing prose -- we're writing code. Our tools should reflect this, and give us as much help as possible.