-- Donald Knuth
-- Donald Knuth
https://softwareengineering.stackexchange.com/a/80092
> Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified.
I'm confused. What do you think the context changes? At least as I read it, both the short form and full context convey the same idea.
Instead, what he meant is that you should profile what part of the code is slow and focus on it first. Knuth didn't say you should be fine with 10-1000x slower code overall.
As was said, profile, find user-impacting bottlenecks, and then optimize.
But, they aren't.
I mean, profile, identify critical components, and rewrite in C (or some other low-level language) for performance is a normal thing for most scripting languages.
> You've got to decide upfront whether the trade off in a rapid prototyping language is good or not, not wait until you've written the project and then profile it.
No, you absolutely don't.
Or to look at it another way: Python with C extensions is effectively another language. You have to consider it as an option along with Pure Python, Rust, Go, C++, Java, FORTRAN, or what have you. Each language has different trade-offs in development time vs performance.
Yes, if you quote Knuth here (whether the short quote or a longer version) you are probably responding to someone whom you believe is engaged in premature optimization.
It remains that the person quoting Knuth isn't claiming that there isn't such a thing as justified optimization. As such, pointing to the context doesn't really add to the conversation. (Nor does a thoughtless quote of Knuth either)
But either way I think the original statement is so uncontroversial and common-sense I actually think it doesn't help any argument unless you're talking to an absolutely clueless dunce or unless you're dealing with someone who somehow believes every optimization is premature.
* Some of the many applications relying on these pieces, could almost certainly use the speedup and for those it wouldn't be premature
* The return of investment is massive due to the scale
* There are tremendous productivity gains by increasing the performance baseline because that reduces the time people have to spend optimizing applications
This is very different from applications where you can probably define performance objectives and define much more clearly what is and isn't premature.a) gives a rule-of-thumb estimate of how much optimisation to do (maybe 3% of all opportunities);
b) explains that non-premature opimisation is not just not the root of all evil but actually a good thing to do; and
c) gives some information about how to do non-premature optimisation, by carefully identifying performance bottlenecks after the unoptimised code has been written.
I agree with GP that unless we know what Knuth meant by "premature" it is tempting to use this quote to justify too little optimisation.
And it's got commercial interests willing to throw money at performance now because of that.
Seems like the Python community, whether as top-down strategy or emergent aggregate of grassroots decisions made the right choices here.
Languages don't succeed on their technical merit. They succeed by being good enough to gain traction, after which it is more about market forces. People choose Python for it's great ecosystem and the availability of developers, and they accept the price they pay in performance. But that doesn't imply that performance wasn't an issue in the past, or that Python couldn't have been even more successful if it had been more performant.
And to be clear, I use Python every day, and I deeply appreciate the work that's been put into 3.10 and 3.11, as well as the decades prior. I'm not interested in prosecuting the decisions about priorities that were made in the past. But I do think there are lessons to be learned there.
In my experience it's far more common for "optimizations" to be technical debt than the absence of them.
> only ever think about performance in retrospect
From the extra context it pretty much does mean that. "but only after that code has been identified" - 99.999% of programmers who think they can identify performance bottlenecks other than in retrospect are wrong, IME.
It is not possible to predict bottlenecks in computation, no. But the implications of putting global state behind a mutex in a concurrent application should be clear to the programmer, and they should think seriously before making a choice like that. If you think of a different way to do that while the code is still being written, you'll avoid trapping yourself in an irreversible decision.