Why do you like managing your own memory exactly? Modern GCs are quite good, so the domain in which you can beat their performance is narrow and will continue getting narrower as time goes on.
The software performance gap between modern GC code and non-GC code is still pretty large almost everywhere. GCs make entire classes of optimization effectively impossible. At the limit, GCs are an abstraction that is always going to make worse runtime choices than purpose-built code.
GCs are useful in the same way that Python is useful even though it is slow. Simplicity of use has intrinsic value but that is a tradeoff against other objectives.
I agree that GC code can be and usually is slower. But as a counterpoint: allocation can be very slow. Bump allocation is fast. If you know your lifetimes and can free all of your bump-allocated memory in one go, that's pretty much the best you can do. If not, then you can still bump-allocate, but copy away the live stuff while discarding the rest. You keep bump allocation, you may even improve locality by eliminating the fragmentation in your bump allocation arena. On the other hand, you've written a garbage collector and thus inherit the disadvantages of GC.
My point is that you can start out without a GC and do a series of sane and effective optimizations that end you up with a GC. Just as you can start with a GC and optimize by moving more and more of your allocations to non-GC memory and end up without a GC. Which endpoint is faster depends on the workload.
> At the limit, GCs are an abstraction that is always going to make worse runtime choices than purpose-built code.
You can say the same about any abstraction, such as having a generic memory allocator, using a standard library, actually about any code reuse. For example, many programs use printf, but don’t need all its features, so hand-rolling a custom version may lead to smaller, faster code (things get complicated here on systems with shared libraries)
The question always is whether lost performance (execution time, memory usage) is worth faster development.
I guess I like the idea of having to think a little more deeply about how memory is used while I'm programming. I know that might sound a bit odd, but before I started learning and using rust, I remember being much less aware of certain things while programming, and then discovering much later that I did something very sub-optimally. So rust is kind of a forcing function in a way - it makes me write better code.
I have also worked on projects (web apps) where GC pauses became annoying to end-users. I wouldn't say this is the fault of GC perse, but writing code without a GC, seems to prevent some performance problems for me, and can also make performance problems stand out sooner in the dev cycle.
Many modern GC languages and runtimes have benefited greatly from improved escape analysis, which identifies memory allocations that have short, identifiable lifetimes, and removes those from the GC-managed heap entirely.
Of course, many GCs have indeed gotten better in their own right, but not using the GC at all remains the most potent optimization.
GCs are useful in the same way that Python is useful even though it is slow. Simplicity of use has intrinsic value but that is a tradeoff against other objectives.