Live data from Hacker News

Rob Pike’s Rules of Programming (1989)

users.ece.utexas.edu

21–30 of 332 posts

Re: Rob Pike’s Rules of Programming (1989)

#21
post #2

"Write stupid code that uses smart objects" That's a good one. It's amazing how much complexity can be created by using the wrong abstractions.

I frequently find that, when refactoring especially, you find a lot of big ol' god objects that are incomprehensible. But when you break them down into 5-10 small objects, suddenly the operation they were trying to do makes perfect sense.

mmmm very true with Redux --> context+hook state

Re: Rob Pike’s Rules of Programming (1989)

#22
post #7

Am I wrong to avoid writing O(n^2) code if at all possible when it is fairly easy to use hash tables for a better time complexity? Sure when n is small the O(n^2) one will be faster but when n is small /anything/ you do is fast in absolute terms so I'm trying to not leave traps in my code just waiting for n to get bigger than initially expected.

> Am I wrong to avoid writing O(n^2) code if at all possible when it is fairly easy to use hash tables for a better time complexity

Are you sure that std::unordered_map is faster than std::vector? Did you measure?

Every time you access an element in std::vector, you also access nearby ones (thanks to L1 cache, as well as CPU-prefetching of in-line data).

In contrast, your std::unordered_map or hash-table has almost no benefits to L1 cache. (It should be noted that linear-probing, despite being a O(N^2) version of hash-tables worst-case, is actually one of the better performers due to L1 cache + prefetching)

Re: Rob Pike’s Rules of Programming (1989)

#23
post #7

Am I wrong to avoid writing O(n^2) code if at all possible when it is fairly easy to use hash tables for a better time complexity? Sure when n is small the O(n^2) one will be faster but when n is small /anything/ you do is fast in absolute terms so I'm trying to not leave traps in my code just waiting for n to get bigger than initially expected.

Keep in mind that a lot of this was written during an era where even modestly complex data structures/algorithms had to be rolled by hand.

The philosophy is really to not waste time implementing optimizations that may not be necessary. Naturally you should reach for the best tool you have in your tool box. So if you language of choice has a hashmap that can be used with no additional work, go for it. But don't wait two days rolling your own red-black tree because it might be better.

Re: Rob Pike’s Rules of Programming (1989)

#24

It turns out rule 5 (Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident) is both true but also hard. Eric Evans' Domain Driven Design is a good book on the topic.

Not only is it hard, it's the one thing that if you get it right, your technical foundation will be rock solid. But it's the thing most teams and organizations neglect to spend enough time on. I often wonder why this is the case -- my first mentors taught me that logical data modeling was a really important skill. But I never talk about third normal form or any such things with my peers.

Re: Rob Pike’s Rules of Programming (1989)

#25
post #7

Am I wrong to avoid writing O(n^2) code if at all possible when it is fairly easy to use hash tables for a better time complexity? Sure when n is small the O(n^2) one will be faster but when n is small /anything/ you do is fast in absolute terms so I'm trying to not leave traps in my code just waiting for n to get bigger than initially expected.

I think, in most cases, if you have n items in memory, and you want to find m of them by id, or some such thing, your default should be to represent the n items as a hashmap, not a list, and look them up from the hashmap. There will be cases where this isn’t the right choice, but it’s a good default. And it’s almost always virtually no extra complexity to represent them this way, i.e. often something as simple as: myMap = myList.groupBy(_.id)

Don’t write complex optimizations until you know you need them, but I think defaulting to code with good O(N) complexity, where it’s simple to do so, is a good default.

Re: Rob Pike’s Rules of Programming (1989)

#26
post #7

Am I wrong to avoid writing O(n^2) code if at all possible when it is fairly easy to use hash tables for a better time complexity? Sure when n is small the O(n^2) one will be faster but when n is small /anything/ you do is fast in absolute terms so I'm trying to not leave traps in my code just waiting for n to get bigger than initially expected.

Yeah, I do well writing dumb inefficient code as default, and optimizing it when needed, which is almost never.

If I know beforehand we'll handle a lot of data, I can pick something fast and complex to begin with, but that effort is probably mostly a waste.

Re: Rob Pike’s Rules of Programming (1989)

#27

> "write stupid code that uses smart objects". Writing stupid code is actually really difficult. For me, it takes a little bit of iterating before I know just the right place to insert stupid.

Do you use TDD? I'm not religious about it in general, but when I'm lost, confused, and easily distracted, I start with TDD to write the dumbest possible code.

Re: Rob Pike’s Rules of Programming (1989)

#28
post #7

Am I wrong to avoid writing O(n^2) code if at all possible when it is fairly easy to use hash tables for a better time complexity? Sure when n is small the O(n^2) one will be faster but when n is small /anything/ you do is fast in absolute terms so I'm trying to not leave traps in my code just waiting for n to get bigger than initially expected.

Use whatever makes for clearer code, unless you are certain it's the bottleneck.

Re: Rob Pike’s Rules of Programming (1989)

#29
post #7

Am I wrong to avoid writing O(n^2) code if at all possible when it is fairly easy to use hash tables for a better time complexity? Sure when n is small the O(n^2) one will be faster but when n is small /anything/ you do is fast in absolute terms so I'm trying to not leave traps in my code just waiting for n to get bigger than initially expected.

Using array based data structures also get you more cache hits. For smaller data sets, this may well be faster than a fancy algorithm.

This is true only if you are iterating over the entire array often. If you only rarely need to access one data member the array will not be in cache and so you have less to load from memory. Depending on how your data is structured the array may or may not save time even in small sizes.

Re: Rob Pike’s Rules of Programming (1989)

#30

Rule 5 seems to mirror one of my favorite insights from Alexander Stepanov: > In 1976, still back in the USSR, I got a very serious case of food poisoning from eating raw fish. While in the hospital, in the state of delirium, I suddenly realized that the ability to add numbers in parallel depends on the fact that addition is associative. (So, putting it simply, STL is the result of a bacterial infection.) In other wo…

And that was 10 years before Haskell went huge in that idea.
Post reply on HN