I mean, sure, but it really does depend on what you're doing. If you're working on a library with collection-types and you want to make each iteration as fast as possible, then roll up your sleeves. If you're writing a compiler and you want your language's source-code to finish compiling this week, roll up the sleeves. If you're working on a game-engine and you want to draw more than everyone else, roll up the sleeves...
There are plenty of real-world reasons why you'd want to get knee deep in this stuff. I wasn't suggesting not using tools (I've literally spent the day buried in JetBrains' memory and tracing tools!), but those tools can only tell you what is happening now, not what to do to improve it.
Profiling is, of course, essential. But performance tweaking can be quite a laborious process: if you're judging things by big-O notation, then that's a different level above the real low-level tweaking (imho of course). Picking the correct data-structures is all in the 101 of performance engineering. That's in the literature. But it's all too basic and simplistic. Most performance minded engineers wouldn't need a profiling tool to know which data-structure to use.
At the smallest level there's a lot of mental theory building and experimentation as you try out different approaches, which is where the instinct and intuition starts to build. I never see any of that in discussions about performance engineering.
> but those tools can only tell you what is happening now, not what to do to improve it.
They tell you what's happening now, but they also tell you if what you've done has had a positive impact.
> If you're judging things by big-O notation, then that's a different level above the real low-level tweaking (imho of course).
I completely agree. My point isn't that Big-Oh is low level, but rather that Big-Oh is often enough for most programming problems. Even in some of your examples like a compiler, game engine, or collection library, the big oh matters and if it's wrong, that can be a lot more important than shaving 0.1% on writing a function in a low level fashion. Big-Oh is gotten wrong a surprising amount of time even though it's 101 level stuff.
> At the smallest level there's a lot of theory building and experimentation as you try out different approaches, which is where the instinct and intuition starts to build. I never see any of that in discussions about performance engineering.
Oh because people get these things wrong all the time. That's why performance engineering stresses that you test, test, test and know what your testing and know why your testing could be wrong or corrupted. You should not trust your intuition because things change and it isn't always correct.
A good example of how easy it is to get measuring wrong. Imagine you start tweaking a function and you measure that your application became 1% faster. Was it the work you did on that function? Surprisingly, not always (at least not directly). Sometimes, it's the case that when you work on a function you re-align other functions as the machine code has to go it memory. It's possible that an undiscovered misaligned while loops was actually causing a large portion of your performance spill and by tweaking the function here, you aligned the while loop (or maybe a few of them). And, importantly, a new change somewhere else might re-unalign that same while loop.
You walk away thinking you've learn some low level lesson when in actuality your bit twiddling simply accidentally fixed something somewhere else.
This is why measuring is so important but also good measuring is even more important.