Live data from Hacker News

Rob Pike’s Rules of Programming (1989)

users.ece.utexas.edu

81–90 of 122 posts

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

#81
post #60

Earlier quoted context omitted.

> which offers a lookup method, and which both HashSet and Lists implement How does a List map values to key? How does it even represent them?

The lookup method just checks whether an element exists in a collection or not. List and HashSet implement non-indexable collections, which have no notion of key. The Collection interface is very thin, and it's mostly used when you need to keep track of a set of elements. E.g. storing the nodes already visited in a dfs.

OK I know more about C# now than I ever planned on knowing.

The problem with OP comment is that KISS and premature optimization are not diametrically opposed. Thet are two separate principles that mean different things.

Premature optimization is bad, but not because it necessarily violates KISS. Similarly, many people overcomplicate code for reasons nothing to do with optimization.

His argument reminds me of people who argue against free speech generally because we already ban people shouting fire in a cinema.

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

#82

Earlier quoted context omitted.

Ironically, in that situation, using a list might end up being more efficient due to cache locality. Or not. That's why measuring is so important, since performance can be a very counterintuitive subject. Hard-data should always prevail over theory and guesswork.

"Lists", presumably referencing a linked list, have horrible cache locality. You were thinking of an array?

The rise of Python and similar languages have muddied the distinction between "lists" and "arrays".

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

#83
post #63
post #53

Earlier quoted context omitted.

In terms of programmer time/effort, using .Get() is simpler. In terms of program speed/optimization, the answer depends on how .Get() is implemented.

Writing simple programs that meets requirements should be your goal. Premature optimization is the root of all evil.

Simplicity is great when it's not borne of ignorance and when it doesn't over-simplify. Some things are unavoidably complex. Even the word "simple" is complex, and has many meanings. What if simple is defined as...

- relies on simple "Programming 101" concepts

- doesn't require using or learning a framework or library

- corollary to above, doesn't require ascertaining that said framework or library implements a .Get() method

- doesn't rely on anyone else's code and has no dependencies or references

- doesn't require understanding ancillary concepts that might be present such as hash tables

Then writing the loop is "simpler." To answer your original question.

And just to turn things completely topsy-turvy, how about your .Get() method. If it's implemented the way such things are usually implemented, that means it uses hash tables and is very efficient. But that means it's a premature optimization, right, and therefore the devil? (Well we haven't defined "premature" either.)

The real answer is to think for yourself like a grown-up and don't rely on dogma. Every situation is different; tackle every problem by optimizing for what's important in that specific problem, using whatever resources and minding whatever constraints apply to that specific problem.

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

#84
post #27

Rule 6: Every well-intentioned rule will be bastardized and used to justify horrible code. Foo: "Hey, this 10000-element collection, which we do repeated lookups on... why are we using a list and not a HashSet?" Bar: "Because lists are so much simpler than a HashSet. Let's just KISS" Foo: "But... doing repeated lookups on a 10k sized list is so much slower than just using a HashSet!" Bar: "Oh really? Have you profile…

Ironically, in that situation, using a list might end up being more efficient due to cache locality. Or not. That's why measuring is so important, since performance can be a very counterintuitive subject. Hard-data should always prevail over theory and guesswork.

Isn't a degenerate hash set a linked list?

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

#85

Earlier quoted context omitted.

Your "Get" method hides complexity. It could be that it loops over a list, or that it hashes to find the bin, then loops over the list of items in the bin, or any of other dozens of other possible implementations. So the next question is "What's the implementation of the Get(key) method?" Or maybe "Why aren't you using your language's library methods to loop over that list?"

Is this really an explanation of why manually iterating over a list is simpler than just calling a method? Get is simpler precisely because it hides the complexity. > Or maybe "Why aren't you using your language's library methods to loop over that list?" What makes those methods not subject to the "hiding complexity" objection?

It's an ill-considered stream of consciousness where I wasn't clearly separating "simplicity of interface" from "simplicity of implementation".

Part of what I was going for is that a clean interface might hide a complex implementation. If you've followed rule 1 and see that "Get" is a bottleneck, it makes sense to apply rules 3+4, and see if there isn't a simpler implementation than the one provided by "Get".

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

#86
post #62

Earlier quoted context omitted.

Your "Get" method hides complexity. It could be that it loops over a list, or that it hashes to find the bin, then loops over the list of items in the bin, or any of other dozens of other possible implementations. So the next question is "What's the implementation of the Get(key) method?" Or maybe "Why aren't you using your language's library methods to loop over that list?"

Why are you even asking the question if profiling hasn't determined a performance problem in that bit of code?

I'm considering cases where looping over a list mean using a simpler algorithm than whatever's provided by "Get", applying rules #3+#4, after determining that "Get" is a bottleneck.

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

#87
post #27

Rule 6: Every well-intentioned rule will be bastardized and used to justify horrible code. Foo: "Hey, this 10000-element collection, which we do repeated lookups on... why are we using a list and not a HashSet?" Bar: "Because lists are so much simpler than a HashSet. Let's just KISS" Foo: "But... doing repeated lookups on a 10k sized list is so much slower than just using a HashSet!" Bar: "Oh really? Have you profile…

Ironically, in that situation, using a list might end up being more efficient due to cache locality. Or not. That's why measuring is so important, since performance can be a very counterintuitive subject. Hard-data should always prevail over theory and guesswork.

Bad practitioners in any field crudely invoke and naively apply a trite toolbox of mantras. Detached from reality and driven by insecure ego, they become the problem by using magical thinking from authoritarian logic and delude themselves of the reality of what they are actually doing.

In any skill, people can fall prey to cults of myth and mysticism as they merit based on adherence to orthodoxy rather than suitability. Programming is no different and sometimes it's hard to hear anybody think over the mooing of all the sacred cows.

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

#89

The sum of these rules seem to imply that it's difficult to theoretically model programming, so always wait for your program to be fully written so you can perform some brute force empiricism -- and only then think about performance.

Can you define "theoretically model programming"?

He doesn't imply that from what I read. He simply said be empirical and practical. Let data (inputs and what you measure) speaks for itself. This is like the simplified version of scientific method in the context of programming.

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

#90

Having spent a great deal of time - most of my career, really, doing performance optimization, some of this rings true, but much of it doesn't. Rule 2 only applies if you can just decide that your current level of performance is "pretty great" and then parachute away to another project. Otherwise if you find that, instead of 1 hot spot taking 80% of your time, you have 5 warm spots taking 16% of your time, you have 5…

So much this, there's nothing I dread so much as a "flat profile".

These rules are great if you actually have a smoking gun, however if you're getting killed by random memory access patterns they rarely present that way.

Post reply on HN