An audio mixer would be the same - it's given some fraction of the time to mix (resample, apply effects, etc.) in some short amount of time (say 5ms) - and called at regular periods.
I don't know much about web-servers, but wouldn't that be the case there - you want quick response (html).
I'm not saying going against scripting/dynamic/garbage-collected languages - they are very useful - but often there is need for the garbage collection mechanism to be exposed, so that it could be done piecewise, or fully collected at timees when it does not matter (say in a game, when transitioning from one level to another, or some UI is popped on the screen (pause), etc.).
E.g. - it's important for such things to be exposed, rather than hidden (and most of the time they are). For example reference lua, and luajit are good examples there, and other runtime implementations allow that (.NET I think there is a way to pause the garbage collectro).
But performance is needed in all mentioned applications above - physics, collision, occlusion, rendering, etc.
…is one of the most demanding application ever. And a tiny niche to boot: while prominent, games represent a tiny fraction of all programming effort. Web browsers and operating systems are an even more extreme example of this availability bias.
For interactive stuff that otherwise doesn't move (regular web browsing, GUI stuff…), 100ms response time is perfect, except maybe for text entry. GC pauses can be made negligible in that context. (Though as you said, we need access to that stuff.)
People often greatly underestimate the amount of performance sensitive software out there, often because they're used to working on software where the hardware isn't a fixed constraint, or are indirectly relying on optimized C/C++ software provided by the system itself.
Moreover, simple benchmarks which are often used for comparing languages are not a valid indicator of the performance available in a lower-level language.
For example, switching loop-processed data from a standard AOS (array of structures) to a SOA (structure of arrays) format can improve performance by orders of magnitude by reducing cache misses (on an i7, main memory latency is ~25x that of L1 cache).
With that latency difference in mind, imagine for a moment the impact of iterating an array of objects stored disparately in memory versus a tightly packed array.
Or more related to memory management, a common allocation optimization used in games is to provide a block of per-frame memory; allocations are a simple addition, and deallocation is an assignment. All the easy cleanup of GC, but with a constant (and insignificant) cost.
Certainly most of the code does not need to be C++, nor heavily optimized; even the 16/32ms per frame game industry tends towards garbage collected scripting languages for a significant portion of the code base. That does not however obviate the necessity for a systems level language to provide the capacity for such optimization.
I call availability bias: people who work on high performance niches feel everyone is underestimating the problem. People who work on low-performance niches wonder what's the big deal.
What I have personally observed is more like a fear of poor performance, coming from people who don't understand the problem like you do. So the team choose C++, which eventually leads to an unmaintainable, slow Big Ball of Mud. 'Cause as your AOS vs SOA example demonstrates, C++ doesn't magically make your code fast. Oops.
> That does not however obviate the necessity for a systems level language to provide the capacity for such optimization.
Agreed. Just two caveats: first, C++ is really a last resort, to be used when nothing else will do, not even C+Lua or similar combination. Even for high performance code, this language is way overused. Second, while we all use the high performance infrastructure you speak of, few of us get to write it.
I think you're right about that, but I also think that people greatly underestimate the determinism gap between them, too. (Not necessarily the same set of people, of course.)
Also don't forget that garbage collectors can often be tuned. Granted, many of them suck, but a generational, incremental collector whose parameters can be tweaked? Much less room for pauses.
Also, some naive simulations will adapt the length of their steps with the time it takes to compute them. Any performance variation gives you full blown unpredictability.
When you're just CPU bound without having to cope with lots of memory transfer / throughput, then you won't notice.
Without a doubt, there are many apps that don't need this pure speed, but for specialist apps and even general apps on the desktop (compare firefox to chrome and safari for example), you can notice the difference quite distinctly.
In my experience writing high performance applications for the VFX industry, where both memory performance AND memory compactness (so you can fit as much in memory as possible) are important, when profiling applications, I've found that maybe 70% of the time it's the memory allocation / deallocation that's the actual bottleneck, not actual calculations. Being able to separate stuff into separate allocators based on different use cases adds complexity, but gives huge benefits when you're memory throughput constrained.
My feeling is that most often, (i) people don't need nearly as much performance as they think, and (ii) they greatly overestimate the performance gap between C++ and garbage collected languages (most notably those who are compiled to native code, such as Lisp, ML, and Haskell).