And I never said anything remotely close to contradict this statement.
> Knowing where performance issues with certain techniques might arise is not premature optimization.
It is:
- Python: should I use a for loop, a list comprehension or the map function?
- C++: should I use a std::list, std::vector, ...?
- Go: should I use interface{} or generics?
The difference between those options is subtle and completely unrelated to the problem you want to solve.> Implement with an appropriate level of care, including performance concerns.
Step 1: solve your problem naively, aka: make it work
Step 2: add tests, separate business logic from implementation details, aka: make it right
Step 3: profile / benchmark to see where the chokepoints are and optimize them, aka: make it fast
Chances are that if you have deeply nested loops, generics vs interface{} will be the last of your problems.To take the C++ example again, until you have implemented your algorithm, you don't know what kind of operations (and how often) you will do with your container. So you can't know whether std::list or std::vector fits best.
In Go, until you have implemented your algorithm, you don't know how often you will have to use generics / reflection, so you can't know what will be the true impact on your code.
The "I know X is almost always faster so i'll use it instead of Y" will bite you more often than you can count.
> Not every kind of poor performance appears as a clear spike in a call graph
CPU usage, memory consumption, idling/waiting times, etc... Those are the kind of metrics you care about when benchmarking your code. No one said you only look at spike in a call graph.
But still, to look for such information, you need to have at least a first implementation of your problem's solution. Doing this before is a waste of time and energy because 80% of the time, your assumptions are wrong.
> and even fewer can be fixed without changing any external API.
This is why you "make it work" and "make it right" before you "make it fast".
This way you have a clear separation between your API and your implementation details.