Remix.run Logo
kalaksi 6 hours ago

This shows how hard it is to create a generalized and simple rule regarding programming. Context is everything and a lot is relative and subjective.

Tips like "don't try to write smart code" are often repeated but useless (not to mention that "smart" here means over-engineered or overly complex, not smart).

pydry 4 hours ago | parent [-]

I dunno, Ive seen people try to violate "dont prematurely optimize" probably a thousand times (no exaggeration) and never ONCE seen this happen:

1. Somebody verifies with the users that speed is actually one of the most burning problems.

2. They profile the code and discover a bottleneck.

3. Somebody says "no, but we shouldnt fix that, that's premature optimization!"

Ive heard all sorts of people like OP moan that "this is why pieces of shit like slack are bloated and slow" (it isnt) when advocating skipping steps 1 and 2 though.

I dont think they misunderstand the rule, either, they just dont agree with it.

Did pike really have to specify explicitly that you have to identify that a problem is a problem before solving it?

devnullbrain 4 hours ago | parent [-]

>1. Somebody verifies with the users that speed is actually one of the most burning problems.

Sometimes this is too late.

C++98 introduce `std::set` and `std::map`. The public interface means that they are effectively constrained to being red-black trees, with poor cache locality and suboptimal lookup. It took until C++11 for `std::unordered_map` and `std::unordered_set`, which brought with them the adage that you should probably use them unless you know you want ordering. Now since C++23 we finally have `std::flat_set` and `std::flat_map`, with contiguous memory layouts. 25 years to half-solve an optimisation problem and naive developers will still be using the wrong thing.

As soon as the interface made contact with the public, the opportunity to follow Rob Pike's Rule 5 was lost. If you create something where you're expected to uphold a certain behaviour, you need to consider if the performance of data structures could be a functional constraint.

At this point, the rule becomes cyclical and nonsensical: it's not premature if it's the right time to do it. It's not optimisation if it's functional.

9rx 3 hours ago | parent | next [-]

> the opportunity to follow Rob Pike's Rule 5 was lost.

std::set/std::map got into trouble because they chose the algorithm first and then made the data model match. Rule 5 suggests choosing the right data model first, indicating that it is most important.

pydry 3 hours ago | parent | prev [-]

You've inadvertently made an argument for deprecation, not ignoring rob's rule.

When building interfaces you are bound to make mistakes which end users will end up depending on (not just regarding optimization).

The correct lesson to learn from this is not "just dont make mistakes" but to try and minimize migration costs to prevent these mistakes from getting tightly locked in and try to detect these mistakes earlier on in the design process with more coordinated experimentation.

C++ seems pretty bad at both. It's not unusual, either - migration and upgrade paths are often the most neglected part of a product.

devnullbrain 3 hours ago | parent [-]

How would you have minimised migration costs for std::map?