[HN Gopher] Rob Pike's Rules of Programming (1989)
___________________________________________________________________
Rob Pike's Rules of Programming (1989)
Author : vismit2000
Score : 798 points
Date : 2026-03-18 09:59 UTC (13 hours ago)
(HTM) web link (www.cs.unc.edu)
(TXT) w3m dump (www.cs.unc.edu)
| embedding-shape wrote:
| "Epigrams in Programming" by Alan J. Perlis has a lot more, if
| you like short snippets of wisdom :)
| https://www.cs.yale.edu/homes/perlis-alan/quotes.html
|
| > Rule 5. Data dominates. If you've chosen the right data
| structures and organized things well, the algorithms will almost
| always be self-evident. Data structures, not algorithms, are
| central to programming.
|
| Always preferred Perlis' version, that might be slightly over-
| used in functional programming to justify all kinds of hijinks,
| but with some nuance works out really well in practice:
|
| > 9. It is better to have 100 functions operate on one data
| structure than 10 functions on 10 data structures.
| Intermernet wrote:
| I believe the actual quote is:
|
| "Show me your flowchart and conceal your tables, and I shall
| continue to be mystified. Show me your tables, and I won't
| usually need your flowchart; it'll be obvious." -- Fred Brooks,
| The Mythical Man Month (1975)
| bfivyvysj wrote:
| This is the biggest issue I see with AI driven development.
| The data structures are incredibly naive. Yes it's easy to
| steer them in a different direction but that comes at a long
| term cost. The further you move from naive the more often you
| will need to resteer downstream and no amount of context
| management will help you, it is fighting against the literal
| mean.
| andsoitis wrote:
| > This is the biggest issue I see with AI driven
| development. The data structures are incredibly naive.
|
| Bill Gates, for example, always advocated for thinking
| through the entire program design and data structures
| before writing any code, emphasizing that structure is
| crucial to success.
| neocron wrote:
| Ah Bill Gates, the epitome of good software
| dotancohen wrote:
| Yes, actually. Gates wrote great software.
|
| Microsoft is another story.
| jll29 wrote:
| And Paul Allen wrote a whole Altair emulator so that they
| could use an (academic) Harvard computer for their little
| (commercial) project and test/run Bill Gates' BASIC
| interpreter on it.
| andsoitis wrote:
| > Ah Bill Gates, the epitome of good software
|
| While developing Altair BASIC, his choice of data
| structures and algorithms enabled him to fit the code
| into just 4 kilobytes.
| PaulDavisThe1st wrote:
| I'd like to see Gates or anyone else do that for a
| project that lasts (at least) a quarter century and sees
| a many-fold increase in CPU speed, RAM availability, disk
| capacity etc.
| Intermernet wrote:
| Naive doesn't mean bad. 99% of software can be written with
| understood, well documented data structures. One of the
| problems with ai is that it allows people to create
| software without understanding the trade offs of certain
| data structures, algorithms and more fundamental hardware
| management strategies.
|
| You don't need to be able to pass a leet code interview,
| but you should know about big O complexity, you should be
| able to work out if a linked list is better than an array,
| you should be able to program a trie, and you should be at
| least aware of concepts like cache coherence / locality.
| You don't need to be an expert, but these are realities of
| the way software and hardware work. They're also not super
| complex to gain a working knowledge of, and various LLMs
| are probably a really good way to gain that knowledge.
| dotancohen wrote:
| Then don't let the AI write the data structures. I don't. I
| usually don't even let the AI write the class or method
| names. I give it a skeleton application and let it fill in
| the code. Works great, and I retain knowledge of how the
| application works.
| nostrademons wrote:
| The rule may not hold with AI driven development. The rule
| exists because it's expensive to rewrite code that depends
| on a given data structure arrangement, and so programmers
| usually resort to hacks (eg. writing translation layers or
| views & traversals of the data) so they can work with a
| more convenient data structure with functionality that's
| written later. If writing code becomes free, the AI will
| just rewrite the whole program to fit the new requirements.
|
| This is what I've observed with using AI on relatively
| small (~1000 line) programs. When I add a requirement that
| requires a different data structure, Claude will happily
| move to the new optimal data structure, and rewrite
| literally everything accordingly.
|
| I've heard that it gets dicier when you have source files
| that are 30K-40K lines and programs that are in the
| million+ line range. My reports have reported that Gemini
| falls down badly in this case, because the source file
| blows the context window. But even then, they've also
| reported that you can make progress by asking Gemini to
| come up with the new _design_ , and then asking it to come
| up with a list of modules that depend upon the old
| structure, and then asking it to write a shim layer module-
| by-module to have the old code use the new data structure,
| and then have it replace the old data structure with the
| new one, and then have it remove the shim layer and rewrite
| the code of each module to natively use the new data
| structure. Basically, babysit it through the same
| refactoring that an experienced programmer would use to do
| a large-scale refactoring in a million+ line codebase, but
| have the AI rewrite modules in 5 minutes that would take a
| programmer 5 weeks.
| mock-possum wrote:
| I'm really going to need to see both. There's a lot of
| business logic that simply is not encoded in a data storage
| model.
| mosura wrote:
| Perlis is just wrong in that way academics so often are.
|
| Pike is right.
| Intermernet wrote:
| Hang on, they mostly agree with each other. I've spoken to
| Rob Pike a few times and I never heard him call out Perlis as
| being wrong. On this particular point, Perlis and Pike are
| both extending an existing idea put forward by Fred Brooks.
| mosura wrote:
| Perlis absolutely is not saying the same thing, and as the
| commenter notes the functional community interpret it in a
| particularly extreme way.
|
| I would guess Pike is simply wise enough not to get
| involved in such arguments.
| jacquesm wrote:
| Perlis is right in the way that academics so often are and
| Pike is right in the way that practitioners often are. They
| also happen to be in rough agreement on this, unsurprisingly
| so.
| hrmtst93837 wrote:
| Treating either as gospel is lazy, Perlis was pushing back on
| dogma and Pike on theory, while legacy code makes both look
| cleaner on paper.
| AnimalMuppet wrote:
| Could you be more specific?
| mosura wrote:
| Promoting the idea of one data structure with many
| functions contradicts:
|
| "If you've chosen the right data structures and organized
| things well, the algorithms will almost always be self-
| evident."
|
| And:
|
| "Use simple algorithms as well as simple data structures."
|
| A data structure general enough to solve enough problems to
| be meaningful will either be poorly suited to some problems
| or have complex algorithms for those problems, or both.
|
| There are reasons we don't all use graph databases or
| triple stores, and rely on abstractions over our byte
| arrays.
| AnimalMuppet wrote:
| I think you are badly misinterpreting the statement.
|
| Let's say you're working for the DMV on a program for
| driver's licenses. The idea is to use one structure for
| driver's license data, as opposed to using one structure
| for _new_ driver 's licenses, a different one for
| renewals, and yet a third for expired ones, and a fourth
| one for name changes.
|
| It is _not_ saying that you should use byte arrays for
| driver 's license records, so that you can use the same
| data structure for driver's license data and missile
| tracks. Generalize _within_ your program, not across all
| possible programs running on all computers.
| mosura wrote:
| Your admittedly exaggerated example is arguing against
| the entire concept of relational databases, which is not
| a winning proposition.
|
| You do not write programs with one map of id to thing as
| you are suggesting here.
| rsav wrote:
| There's also:
|
| >I will, in fact, claim that the difference between a bad
| programmer and a good one is whether he considers his code or
| his data structures more important. Bad programmers worry about
| the code. Good programmers worry about data structures and
| their relationships.
|
| -- Linus Torvalds
| mikepurvis wrote:
| I think this is sometimes a barrier to getting started for
| me. I know that I need to explore the data structure design
| in the context of the code that will interact with it and
| some of that code will be thrown out as the data structure
| becomes more clear, but still it can be hard to get off the
| ground when me gut instinct is that the data design isn't
| right.
|
| This kind of exploration can be a really positive use case
| for AI I think, like show me a sketch of this design vs that
| design and let's compare them together.
| ignoramous wrote:
| > _This kind of exploration can be a really positive use
| case for AI I think_
|
| Not sure if SoTA codegen models are capable of navigating
| design space and coming up with optimal solutions. Like for
| cybersecurity, may be specialized models (like DeepMind's
| _Sec-Gemini_ ), if there are any, might?
|
| I reckon, a programmer who already has learnt about /
| explored the design space, will be able to prompt more
| pointedly and evaluate the output qualitatively.
|
| > _sometimes a barrier to getting started for me_
|
| Plenty _great_ books on the topic (:
|
| _Algorithms + Data Structures = Programs_ (1976), https://
| en.wikipedia.org/wiki/Algorithms_%2B_Data_Structures...
| mikepurvis wrote:
| Yeah key word is exploration. It's not "hey Claude write
| the design doc for me" but rather, here's two possible
| directions for how to structure my solution, help me
| sketch each out a bit further so that I can get a better
| sense what roadblocks I may hit 50-100 hours into
| implementation when the cost of changing course is far
| greater.
| sph wrote:
| AI is terrible for this.
|
| My recommendation is to truly learn a functional language
| and apply it to a real world product. Then you'll learn how
| to think about data, in its pure state, and how it is
| transformed to get from point A to point B. These lessons
| will make for much cleaner design that will be applicable
| to imperative languages as well.
|
| Or learn C where you do not have the luxury of using high-
| level crutches.
| sph wrote:
| From what I understand from the vibe coders, they tell a
| machine what the code should do, but not how it should do it.
| They leave the important decisions (the shape of data) to an
| LLM and thus run afoul of this, which is gonna bite them in
| the ass eventually.
| Zamicol wrote:
| That is excellent. I'm putting that in my notes.
| aleph_minus_one wrote:
| > >I will, in fact, claim that the difference between a bad
| programmer and a good one is whether he considers his code or
| his data structures more important. Bad programmers worry
| about the code. Good programmers worry about data structures
| and their relationships.
|
| > -- Linus Torvalds
|
| What about programmers
|
| - for whom the code _is_ a data structure?
|
| - who formulate their data structures in a way (e.g. in a
| very powerful type system) such that all the data structures
| _are_ code?
|
| - who invent a completely novel way of thinking about
| computer programs such that in this paradigm _both_ code and
| data structures are just trivial special cases of some mind-
| blowing concept z of which there exist other special cases
| that are useful to write powerful programs, but these special
| cases are completely alien from anything that could be called
| "code" or "data (structures)", i.e. these programmers don't
| think/worry about code or data structures, but about z?
| mpalmer wrote:
| Was the "J" short for "Cassandra"? When
| someone says "I want a programming language in which I need
| only say what I wish done," give him a lollipop.
| Hendrikto wrote:
| I feel like these are far more vague and less actionable than
| the 5 Pike rules.
| DaleBiagio wrote:
| " 9. It is better to have 100 functions operate on one data
| structure than 10 functions on 10 data structures."
|
| That's great
| mchaver wrote:
| I find languages like Haskell, ReScript/OCaml to work really
| well for CRUD applications because they push you to think about
| your data and types first. Then you think about the
| transformations you want to make on the data via functions.
| When looking at new code I usually look for the types first,
| specifically what is getting stored and read.
| embedding-shape wrote:
| Similarly, that approach works really well in Clojure too,
| albeit with a lot less concern for types, but the "data and
| data structures first" principle is widespread in the
| ecosystem.
| mchaver wrote:
| I've heard good things about Clojure, and it'ss different
| from what I am used to (bonus points because I like an
| intellectual challenge), so trying it out is definitely on
| my todo list.
| linhns wrote:
| Nice to see Perlis mentioned once in a while. Reading SICP
| again, still learning new things.
| WillAdams wrote:
| There is a matching video series for SICP:
|
| https://ocw.mit.edu/courses/6-001-structure-and-
| interpretati...
|
| which I found very helpful in (finally) managing to get
| through that entire text (and do all the exercises).
| 0xpgm wrote:
| Reminded me of this thread between Alan Kay and Rich Hickey
| where Alan Kay thinks "data" is a bad idea.
|
| My interpretation of his point of view is that what you need is
| a process/interpreter/live object that 'explains' the data.
|
| https://news.ycombinator.com/item?id=11945722
|
| EDIT: He writes more about it in Quora. In brief, he says it is
| 'meaning', not 'data' that is central to programming.
|
| https://qr.ae/pCVB9m
| christophilus wrote:
| I'm with Rich Hickey on this one, though I generally prefer
| my data be statically typed.
| 0xpgm wrote:
| Sure, static typing adds some sort of process that provides
| a coarse interpretation of the data.
| johnmaguire wrote:
| Hm, not sure. Data on its own (say, a string of numbers)
| might be meaningless - but structured data? Sure, there may
| be ambiguity but well-structured data generally ought to have
| a clear/obvious interpretation. This is the whole idea of
| nailing your data structures.
| 0xpgm wrote:
| Yeah, structured data implies some processing on raw data
| to improve its meaning. Alan Kay seems to want to push this
| idea to encapsulate data with rich behaviour.
| gregw2 wrote:
| Thanks for the pointer to this 2016 dialog!
|
| One part of it has interesting new resonance in the era of
| agentic LLMs:
|
| _alankay on June 21, 2016 | root | parent | next [-]
|
| This is why "the objects of the future" have to be
| ambassadors that can negotiate with other objects they've
| never seen. Think about this as one of the consequences of
| massive scaling ... _
|
| Nowdays rather than the methods associated with data objects,
| we are dealing with "context" and "prompts".
| 0xpgm wrote:
| Quite a nice insight there!
|
| I should probably be thinking more in this direction.
| JanisErdmanis wrote:
| With 100 functions and one datastructure it is almost as
| programming with a global variables where new instance is
| equivalent to a new process. Doesn't seem like a good rule to
| follow.
| embedding-shape wrote:
| The scope of where that data structure or functions are
| available is a different concern though, "100 functions + 1
| data structure" doesn't require globals or private, it's a
| separate thing.
| JanisErdmanis wrote:
| One can always look as global variables equivalent to a
| context object that's is passed in every function. It's
| just a syntactic difference whether one constructs such
| data structure or uses it implicitly via globals.
|
| What I am getting at is that when one has such gigantic
| data structure there is no separation of concerns.
| CyberDildonics wrote:
| Does one need one's separation of concerns if one's
| concerns shouldn't be separated in the in the first
| place?
|
| Anytime one has access to a database one has access to
| one large global data structure that one can access from
| anywhere is a program.
|
| This same concept goes for one's global state in one's
| game if one is making a game.
| JanisErdmanis wrote:
| Separation of concerns is still a valid paradigm with a
| single global datastructure like GUI, Microservice,
| Database and etc. In such situation one can still
| seperate concerns via composing the global datastructure
| from a smaller units and define methods with respect to
| thoose smaller units. In that way one does not need to
| wonder whether there are some unattended side effects
| when calling a function that mutates the state.
| CyberDildonics wrote:
| Seems like one is backpedaling because one was just
| talking about one's separation of one's concerns and now
| one is defending one's separation of concerns with
| respect to one's global data structure.
| JanisErdmanis wrote:
| I still firmly believe that one ctx object and hundred
| functions/methods is as bad as programming with plain
| variables defined in the global scope. If the ctx is
| composed from smaller data structures with whom the
| functions are defined, then all is good. This is the
| opposite of the rule.
| CyberDildonics wrote:
| But why?
|
| You keep saying you believe it, but that is literally
| what a database is, game state manipulation, string
| manipulation, iterator algorithms, list comprehensions,
| range algorithms, image manipulations, etc. These are all
| instances where you use the same data structures over and
| over with as many algorithms and functions and you need.
| alberto-m wrote:
| This quote from "Dive into Python" when I was a fresh graduate
| was one of the most impacting lines I ever read in a
| programming book.
|
| > Busywork code is not important. Data is important. And data
| is not difficult. It's only data. If you have too much, filter
| it. If it's not what you want, map it. Focus on the data; leave
| the busywork behind.
| bandrami wrote:
| Also basically everything DHH ever said (I stopped using Rails
| 15 years ago but just defining data relationships in YAML and
| typing a single command to get a functioning website and
| database was in fact pretty cool in the oughts).
| Pxtl wrote:
| As much as relational DBs have held back enterprise software
| for a very long time by being so conservative in their
| development, the fact that they force you to put this
| relationship absolutely front-of-mind is _excellent_.
| embedding-shape wrote:
| I'd personally consider "persistence" AKA "how to store shit"
| to be a very different concern compared to the data
| structures that you use in the program. Ideally, your design
| shouldn't care about how things are stores, unless there is a
| particular concern for how fast things read/writes.
| mosura wrote:
| Often significant improvements to every aspect of a system
| that interacts with a database can be made by proper design
| of the primary keys, instead of the generic id way too many
| people jump to.
|
| The key difficulty is identifying what these are is far
| from obvious upfront, and so often an index appears
| adjacent to a table that represents what the table should
| have been in the first place.
| embedding-shape wrote:
| I guess that might be true also, to some extent. I guess
| most of the times I've seen something "messy" in software
| design, it's almost always about domain code being made
| overly complicated compared to what it has to do, and
| almost never about "how does this domain data gets
| written/read to/from a database", although it's very
| common. Although of course storage/persistence isn't non-
| essential, just less common problem than the typical
| design/architecture spaghetti I encounter.
| Pxtl wrote:
| I'm a firm believer in always using an auto-generated
| surrogate key for the PK because domain PKs always
| eventually become a pain point. The problem is that doing
| so does real damage to the ergonomics of the DB.
|
| This is why I fundamentally find SQL too conservative and
| outdated. There are obvious patterns for cross-cutting
| concerns that would mitigate things like this but
| enterprise SQL products like Oracle and MS are _awful_ at
| providing ways to do these reusable cross-cutting
| concerns consistently.
| Pxtl wrote:
| I meant to reply to a different comment originally,
| specifically the one including this quote from Torvalds:
|
| > Good programmers worry about data structures and their
| relationships.
|
| > -- Linus Torvalds
|
| I was specifically thinking about the "relationship"
| issues. The _worst_ messes to fix are the ones where the
| programmer didn 't consider how to relate the objects
| together - which relationships need to be direct PK
| bindings, which can be indirect, which things have to be
| cached vs calculated live, which things _are_ the cache (vs
| the master copy), what the cardinality of each relationship
| is, which relationships are semantically ownerships vs
| peers, which data is part of the system itself vs
| configuration data vs live, how you handle changes to the
| data, (event sourcing vs changelogging vs vs append-only vs
| yolo update), etc.
|
| Not quite "data structures" I admit but absolutely thinking
| hard about the relationship between all the data you have.
|
| SQL doesn't frame _all_ of these questions out for you but
| it 's good getting you to start thinking about them in a
| way you might not otherwise.
| tangus wrote:
| Aren't they basically saying opposite things? Perlis is saying
| "don't choose the right data structure, shoehorn your data into
| the most popular one". This advice might have made sense before
| generic programming was widespread; I think it's obsolete.
| Rygian wrote:
| Pike: strongly typed logic is great!
|
| Perlin: stringly typed logic is great!
| embedding-shape wrote:
| > Perlis is saying "don't choose the right data structure,
| shoehorn your data into the most popular one"
|
| I don't take it like that. A map could be the right data
| structure for something people typically reach for classes to
| do, and then you get a whole bunch of functions that can
| already operate on a map-like thing for free.
|
| If you take a look at the standard library and the data
| structures of Clojure you'd see this approach taken to a
| somewhat extreme amount.
| TYPE_FASTER wrote:
| > Rule 5. Data dominates. If you've chosen the right data
| structures and organized things well, the algorithms will
| almost always be self-evident. Data structures, not algorithms,
| are central to programming.
|
| If I have learned one thing in my 30-40 years spent writing
| code, it is this.
| seanalltogether wrote:
| I agree. The biggest lesson I try to drive home to newer
| programmers that join my projects is that its always best to
| transform the data into the structure you need at the very
| end of the chain, not at the beginning or middle. Keep the
| data in it's purest form and then transform it right before
| displaying it to the user, or right before providing it in
| the final api for others to consume.
|
| You never know how requirements are going to change over the
| next 5 years, and pure structures are always the most
| flexible to work with.
| bluGill wrote:
| Related: your business logic should work on metric units.
| It is a UI concern if the user wants to see some other
| measurement system. Convert to feet, chains, cubits... or
| whatever obscure measurement system the user wants at
| display time. (if you do get an embedded device that
| reports non-metric units convert when it comes in - you
| will get a different device in the future that reports
| different units anyway)
|
| You still have to worry about someone using kg when you use
| g, but you avoid a large class of problems and make your
| logic easier.
| dcuthbertson wrote:
| But doesn't No. 2 directly conflict with Pike's 5th rule? It
| seems to me these are all aphorisms that have to be taken with
| a grain of salt.
|
| > 2. Functions delay binding; data structures induce binding.
| Moral: Structure data late in the programming process.
| jerf wrote:
| As I'm sure more and more people are using AI to document old
| systems, even just to get a foothold in them personally if they
| don't intend to share it, here's a hint related to that: By
| default, if you fire an AI at a programming base, at least in
| my experience you get the usual documentation you expect from a
| system: This is the list of "key modules", this module does
| this, this module does that, this module does the other thing.
|
| This is the worst sort of documentation; technically true but
| quite unenlightening. It is, in the parlance of the Fred Brooks
| quote mentioned in a sibling comment, _neither_ the
| "flowchart" _nor_ the "tables"; it is simply a brute
| enumeration of code.
|
| To which the fix is, ask for the right thing. Ask for it to
| analyze the key data structures (tables) and provide you the
| flow through the program (the flowchart). It'll do it no
| problem. Might be inaccurate, as is a hazard with all
| documentation, but it makes as good a try at this style of
| documentation as "conventional" documentation.
|
| Honestly one of the biggest problems I have with AI coding and
| documentation is just that the training set is filled to the
| brim with mediocrity and the defaults are inferior like this on
| numerous fronts. Also relevant to this conversation is that AI
| tends to code the same way it documents and it won't have
| either clear flow charts or tables unless you carefully prompt
| for them. It's pretty good at doing it when you ask, but if you
| don't ask you're gonna get a mess.
|
| (And I find, at least in my contexts, using opus, you can't
| seem to prompt it to "use good data structures" in advance, it
| just writes scripting code like it always does and like that
| part of the prompt wasn't there. You pretty much have to come
| back in after its first cut and tell it what data structures to
| create. Then it's really good at the rest. YMMV, as is the way
| of AI.)
| kleiba wrote:
| I believe the "premature evil" quote is by Knuth, not Hoare?!
| swiftcoder wrote:
| Potentially its by either (or even both independently). Knuth
| originally attributed it to Hoare, but there's no paper trail
| to demonstrate Hoare actually coined it first
| Intermernet wrote:
| Turns out that premature attribution is actually the root of
| all evil...
| Bengalilol wrote:
| Every empirical programmer will, at some point, end up
| yelling it out loud (too).
| bsenftner wrote:
| Obvious. Why the elevation of the obvious?
| bazoom42 wrote:
| Definitely not obvious to everybody.
| DrScientist wrote:
| I think for people starting out - rule 5 isn't perhaps that
| obvious.
|
| > Rule 5. Data dominates. If you've chosen the right data
| structures and organized things well, the algorithms will
| almost always be self-evident. Data structures, not algorithms,
| are central to programming.
|
| If want to solve a problem - it's natural to think about logic
| flow and the code that implements that first and the data
| structures are an after thought, whereas Rule 5 is spot on.
|
| Conputers are machines that transform an input to an output.
| mosura wrote:
| > If want to solve a problem - it's natural to think about
| logic flow and the code that implements that first and the
| data structures are an after thought, whereas Rule 5 is spot
| on.
|
| It is?
|
| How can you conceive of a precise idea of how to solve a
| problem without a similarly precise idea of how you intend to
| represent the information fundamental to it? They are
| inseparable.
| DrScientist wrote:
| Obviously they are linked - the question is where do you
| _start_ your thinking.
|
| Do you start with the logical task first and structure the
| data second, or do you actually think about the data
| structures first?
|
| Let's say I have a optimisation problem - I have a simple
| scoring function - and I just want to find the solution
| with the best score. Starting with the logic.
|
| for all solutions, score, keep if max.
|
| Simple eh? Problem is it's a combinatorial solution space.
| The key to solving this before the entropic death of the
| universe is to think about the _structure_ of the solution
| space.
| TheOtherHobbes wrote:
| I mean - no. If you're coming to a completely new domain you
| have to decide what the important entities are, and what
| transformations you want to apply.
|
| _Neither_ data structures _nor_ algorithms, but entities and
| tasks, from the user POV, one level up from any kind of
| implementation detail.
|
| There's no point trying to do something if you have no idea
| what you're doing, or why.
|
| When you know the what and why you can start worrying about
| the how.
|
| Iff this is your 50th CRUD app you can probably skip this
| stage. But if it's green field development - no.
| DrScientist wrote:
| Sure context is important - and the important context you
| appear to have missed is the 5 rules aren't about building
| websites. It's about solving the kind of problems which are
| easy to state but hard to do (well) .
|
| eg sort a list.
| praptak wrote:
| A good chunk of great advice is obvious things _that people
| still fail to do_.
|
| That's why a collection of "obvious" things formulated in a
| convincing way by a person with big street cred is still useful
| and worth elevating.
| pm215 wrote:
| Also, "why these 5 in particular" is definitely not obvious
| -- there are a great many possible "obvious in some sense but
| also true in an important way" epigrams to choose from (the
| Perlis link from another comment has over a hundred). That
| Pike picked these 5 to emphasise tells you something about
| his view of programming, and doubly so given that they are
| rather overlapping in what they're talking about.
| pjc50 wrote:
| You've got to elevate some obviously correct things, otherwise
| social media will fill the void with nonobviously incorrect
| things.
| mosura wrote:
| Better to have 100 comments on one topic than 10 comments on
| 10 topics.
| HunterWare wrote:
| Can't be but so obvious if the first comment I saw here was
| that the first two rules didn't seem so important. =)
| knorker wrote:
| I'd call it more derivative than obvious.
|
| "Why quote someone who's just quoting someone else?" -- Michael
| Scott -- knorker
| heresie-dabord wrote:
| See Tony Hoare:
|
| https://news.ycombinator.com/item?id=47325225
| tobwen wrote:
| Added to AGENTS.md :)
| wwweston wrote:
| How good is your model at picking good data structures?
|
| There's several orders of magnitude less available _discussion_
| of selecting data structures for problem domains than there is
| code.
|
| If the underlying information is implicit in high volume of
| code available then maybe the models are good at it, especially
| when driven by devs who can/will prompt in that direction. And
| that assumption seems likely related to how much code was
| written by devs who focus on data.
| skydhash wrote:
| > There's several orders of magnitude less available
| discussion of selecting data structures for problem domains
| than there is code.
|
| I believe that's what most algorithms books are about. And
| most OS book talks more about data than algorithms. And if
| you watch livestream or read books on practical projects,
| you'll see that a lot of refactor is first selecting a data
| structure, then adapt the code around it. DDD is about data
| structure.
| ozgrakkurt wrote:
| Would be cool to see the live reaction of Rob Pike to this
| comment
| andsoitis wrote:
| > Would be cool to see the live reaction of Rob Pike to this
| comment
|
| Based on everything public, Pike is deeply hostile to
| generative AI in general:
|
| - The Christmas 2025 incident
| (https://simonwillison.net/2025/Dec/26/slop-acts-of-
| kindness/)
|
| - he's labeled GenAI as nuclear waste
| (https://www.webpronews.com/rob-pike-labels-generative-ai-
| nuc...)
|
| - ideologically, he's spent his career chasing complexity
| reduction, adovcating for code sobriety, resource efficiency,
| and clarity of thought. Large, opaque, energy-intensive LLMs
| represent the antithesis.
| clktmr wrote:
| > - he's labeled GenAI as nuclear waste
| (https://www.webpronews.com/rob-pike-labels-generative-ai-
| nuc...)
|
| The whole article is an AI hallucination. It refers to the
| same "Christmas 2025 incident". The internet is dead for
| real.
| phh wrote:
| Unironically. Every time I asked a LLM to make something
| faster, they always tried blind code optimisations, rather than
| measure.
| CharlieDigital wrote:
| I feel like 1 and 2 are only applicable in cases of novelty.
|
| The thing is, if you build enough of the same kinds of systems in
| the same kinds of domains, you can kinda tell where you should
| optimize ahead of time.
|
| Most of us tend to build the same kinds of systems and usually
| spend a career or a good chunk of our careers in a given domain.
| I feel like you can't really be considered a staff/principal if
| you can't already tell ahead of time where the perf bottleneck
| will be just on experience and intuition.
| PaulKeeble wrote:
| I feel like every time I have expected an area to be the major
| bottleneck it has been. Sometimes some areas perform worse than
| I expected, usually something that hasn't been coded well, but
| generally its pretty easy to spot the computationally heavy or
| many remote call areas well before you program them.
|
| I have several times done performance tests before starting a
| project to confirm it can be made fast enough to be viable, the
| entire approach can often shift depending on how quickly
| something can be done.
| pydry wrote:
| The number 1 issue Ive experienced with poor programmers is a
| belief that theyre special snowflakes who can anticipate the
| future.
|
| It's the same thing with programmers who believe in BDUF or
| disbelieve YAGNI - they design architectures for anticipated
| futures which do not materialize instead of evolving the
| architecture retrospectively in line with the future which
| did materialize.
|
| I think it's a natural human foible. Gambling, for instance,
| probably wouldnt exist if humans' gut instincts about their
| ability to predict future defaulted to realistic.
|
| This is why no matter how many brilliant programmers scream
| YAGNI, dont do BDUF and dont prematurely optimize there will
| always be some comment saying the equivalent of "akshually
| sometimes you should...", remembering that one time when they
| metaphorically rolled a double six and anticipated the
| necessary architecture correctly when it wasnt even necessary
| to do so.
|
| These programmers are all hopped up on a different kind of
| roulette these days...
| rcxdude wrote:
| Aye. The number one way to make software amenable to future
| requirements is to keep it simple so that it's easy to
| change in future. Adding complexity for anticipated changes
| works against being able to support the unanticipated ones.
| tbrownaw wrote:
| Sure, don't build your system to keep audit trails until
| after you have questions to answer so that you know what
| needs to go in those audit trails.
|
| Don't insist on file-based data ingestion being a wrapper
| around a json-rpc api just because most similar things are
| moving that direction; what matters is whether someone has
| specifically asked for that for this particular system yet.
|
| .
|
| Not all decisions can be usefully revisited later.
| Sometimes you really do need to go "what if..." and make
| sure none of the possibilities will bite too hard. Leaving
| the pizza cave occasionally and making sure you (have
| contacts who) have some idea about the direction of the
| industry you're writing stuff for can help.
| CharlieDigital wrote:
| > Sure, don't build your system to keep audit trails
| until after you have questions to answer so that you know
| what needs to go in those audit trails...what matters is
| whether someone has specifically asked for that for this
| particular system yet.
|
| I spent ~15 years in life sciences.
|
| _You 're going to build an audit trail, no matter what._
| There's no validated system in LS that does not have an
| audit trail.
|
| It's just like e-commerce; you're going to have a cart
| and a checkout page. There's no point in calling that a
| premature optimization. Every e-commerce website has more
| or less the same set of flows with simply different
| configuration/parameters/providers.
| pydry wrote:
| Going "what if?" and then validating a customer
| requirement that exists NOW is NOT the same thing as
| trying to pre-empt a customer's requirement which _might_
| exist in the future.
|
| Audit trails are commonly neglected coz somebody didnt
| ask the right questions, not coz somebody didnt try to
| anticipate the future.
| projektfu wrote:
| It really depends on your requirements. C10k requires
| different design than a web server that sees a few requests
| per second at most, but the web might never have been
| invented if the focus was always on that level of
| optimization.
| relaxing wrote:
| Rob Pike wrote Unix and Golang, but sure, you're built
| different.
| andsoitis wrote:
| > Rob Pike wrote Unix
|
| Unix was created by Ken Thompson and Dennis Ritchie at Bell
| Labs (AT&T) in 1969. Thompson wrote the initial version, and
| Ritchie later contributed significantly, including developing
| the C programming language, which Unix was subsequently
| rewritten in.
| 9rx wrote:
| Pike didn't create Unix initially, but was a contributor to
| it. He, with a team, unquestionably wrote it.
| andsoitis wrote:
| > but was a contributor to it. He, with a team,
| unquestionably wrote it.
|
| contribute < wrote.
|
| His credits are huge, but I think saying he wrote Unix is
| misattribution.
|
| Credits include: Plan 9 (successor to Unix), Unix Window
| System, UTF-8 (maybe his most universally impactful
| contribution), Unix Philosophy Articulation,
| strings/greps/other tools, regular expressions, C
| successor work that ultimately let him to Go.
| 9rx wrote:
| Are you under the impression he was, like, a hands-off
| project manager or something? His involvement was in
| writing it. Not singlehandedly, but certainly as part of
| a team. He unquestionably wrote it. He did not envision
| it like he did the other projects you mention, but the
| original credit was only in the writing of.
| amw-zero wrote:
| To say "Rob Pike wrote Unix" is completely inaccurate. He
| joined after v7, in 1980.
| 9rx wrote:
| Nobody seems to be questioning that he was involved in
| Unix. Given that he didn't write it, what _did_ he do for
| the project? Quality assurance? Support? Marketing? Court
| jester?
| Intermernet wrote:
| Rob Pike is responsible for many cool things, but Unix isn't
| one of them. Go is a wonderful hybrid (with its own faults)
| of the schools of Thompson and Wirth, with a huge amount of
| Pike.
|
| If you'd said Plan 9 and UTF-8 I'd agree with you.
| jacquesm wrote:
| Rob Pike definitely wrote large chunks of Unix while at
| Bell Labs. It's wrong to say he wrote all of it like the GP
| did but it is also wrong to diminish his contributions.
|
| Unless you meant to imply that UNIX isn't cool.
| relaxing wrote:
| I did not say he wrote all of it. "Write" can include co-
| authorship.
|
| A lot of people are learning some history today,
| beautiful to see.
| jacquesm wrote:
| I think that if you meant co-authorship you could have
| made that clearer. A 'contributed to' would have saved
| some unique ids.
| my-next-account wrote:
| Do you think Rob Pike ever decided that maybe what was done
| before isn't good enough? Stop putting artificial limits on
| your own competency.
| HunterWare wrote:
| ROFL, I wish Pike had known what he was talking about. /s ;)
| CharlieDigital wrote:
| Rob Pike and I (and probably most of us) work(ed) on
| different kind of things.
|
| Notice my use of the word "Novelty".
|
| I get hired because I'm very good at building specific kinds
| of systems so I tend to build many variants of the same kinds
| of systems. They are generally not that different and the
| ways in which the applications perform are similar.
|
| I do not generally write new algorithms, operating systems,
| nor programming languages.
|
| I don't think this is so hard to understand the nuance of
| Pike's advice and what we "mortals" do in or day-to-day to
| earn a living.
| Bengalilol wrote:
| > you can kinda tell where you should optimize ahead of time
|
| Rules are "kinda" made to be broken. Be free.
|
| I've been sticking to these rules (and will keep sticking to
| them) for as long as I can program (I've been doing it for the
| last 30 years).
|
| IMHO, you can feel that a bottleneck is likely to occur, but
| you definitely can't tell where, when, or how it will actually
| happen.
| Mercuriusdream wrote:
| never expected it to be a single HTML file so kind of surprised,
| but straight to the point, to be honest.
| andsoitis wrote:
| KISS
| epolanski wrote:
| Well, even simpler, could've been plain text, every browser
| supports them.
| anthk wrote:
| 9front it's distilled Unix. I corrected Russ Cox' 'xword' to work
| in 9front and I am just a newbie. No LLM's, that's Idiocratic,
| like the movie; just '9intro.us.pdf' and man pages.
|
| LLM's work will never be reproducible by design.
| piranha wrote:
| > Rule 5 is often shortened to "write stupid code that uses smart
| objects".
|
| This is probably the worst use of the word "shortened" ever, and
| it should be more like "mutilated"?
| andsoitis wrote:
| Syntactic sugar is cancer of the semicolon.
| franktankbank wrote:
| Tide goes in tide goes out, can't explain that.
| paradox460 wrote:
| Tide goes in, clean laundry comes out
| keyle wrote:
| Rule 5 is definitely king. Code acts on data, if the data is
| crap, you're already lost.
|
| edit: s/data/data structure/
| andsoitis wrote:
| ... if the data structures are crap.
|
| Good software can handle crap data.
| keyle wrote:
| That is not what I meant. I meant crap data structures. Sorry
| it's late here.
| DaleBiagio wrote:
| The attribution to Hoare is a common error -- "Premature
| optimization is the root of all evil" first appeared in Knuth's
| 1974 paper "Structured Programming with go to Statements."
|
| Knuth later attributed it to Hoare, but Hoare said he had no
| recollection of it and suggested it might have been Dijkstra.
|
| Rule 5 aged the best. "Data dominates" is the lesson every senior
| engineer eventually learns the hard way.
| zabzonk wrote:
| I've always thought it was Dijkstra - it even sounds Dijkstra-
| ish.
| YesThatTom2 wrote:
| If Dijkstra blamed Knuth it would have been the best recursive
| joke ever.
| elcapitan wrote:
| Meta: Love the simplicity of the page, no bullshit.
|
| Funny handwritten html artifact though: <title>
| <h1>Rob Pike's 5 Rules of Programming</h1> </title>
| divbzero wrote:
| Yes, I noticed this too. Timeless wisdom in 2128 bytes of
| handcrafted HTML.
| doe88 wrote:
| Great rules, but Rule 3.: WOW, so true, so well enunciated,
| masterful.
| bell-cot wrote:
| Yes, and I'd say it's more true now than then. Best case, your
| fancy algorithms are super-sizing code that runs 1% of the
| time, always kicking more-often-run code out of the most
| critical CPU caches. Worst case, your fancy algorithms contain
| security bugs, and the bad guys cash in.
| Devasta wrote:
| > "Premature optimization is the root of all evil."
|
| This Axiom has caused far and away more damage to software
| development than the premature optimization ever will.
| gjadi wrote:
| Because people only quote it partially.
|
| > We should forget about small efficiencies, say about 97% of
| the time: premature optimization is the root of all evil. Yet
| we should not pass up our opportunities in that critical 3%.
| nateb2022 wrote:
| Previous discussion:
| https://news.ycombinator.com/item?id=15776124 (8 years ago, 18
| comments)
| tomhow wrote:
| Here's the full set:
|
| _Rob Pike's Rules of Programming (1989)_ -
| https://news.ycombinator.com/item?id=38097031 - Nov 2023 (259
| comments)
|
| _Rob Pike's Rules of Programming (1989)_ -
| https://news.ycombinator.com/item?id=24135189 - Aug 2020 (323
| comments)
|
| _Rob Pike's Rules of Programming (1989)_ -
| https://news.ycombinator.com/item?id=15776124 - Nov 2017 (18
| comments)
|
| _Rob Pike's Rules of Programming (1989)_ -
| https://news.ycombinator.com/item?id=15265356 - Sept 2017 (112
| comments)
|
| _Rob Pike's Rules of Programming (1989)_ -
| https://news.ycombinator.com/item?id=7994102 - July 2014 (96
| comments)
| jcmartinezdev wrote:
| Rule 6: Never disagree with AI slop
| igtztorrero wrote:
| Rule 4, I have always practiced and demanded of junior
| programmers, to make algorithms and structures that are simple to
| understand, for our main user: the one who will modify this code
| in the future.
|
| I believe that's why Golang is a very simple but powerful
| language.
| anymouse123456 wrote:
| There are very few phrases in all of history that have done more
| damage to the project of software development than:
|
| "Premature optimization is the root of all evil."
|
| First, let's not besmirch the good name of Tony Hoare. The quote
| is from Donald Knuth, and the missing context is essential.
|
| From his 1974 paper, "Structured Programming with go to
| Statements":
|
| "Programmers waste enormous amounts of time thinking about, or
| worrying about, the speed of noncritical parts of their programs,
| and these attempts at efficiency actually have a strong negative
| impact when debugging and maintenance are considered. We should
| forget about small efficiencies, say about 97% of the time:
| premature optimization is the root of all evil. Yet we should not
| pass up our opportunities in that critical 3%."
|
| He was talking about using GOTO statements in C. He was talking
| about making software much harder to reason about in the name of
| micro-optimizations. He assumed (incorrectly) that we would
| respect the machines our software runs on.
|
| Multiple generations of programmers have now been raised to
| believe that brutally inefficient, bloated, and slow software is
| just fine. There is no limit to the amount of boilerplate and
| indirection a computer can be forced to execute. There is no
| ceiling to the crystalline abstractions emerging from these
| geniuses. There is no amount of time too long for a JVM to spend
| starting.
|
| I worked at Google many years ago. I have lived the absolute
| nightmares that evolve from the willful misunderstanding of this
| quote.
|
| No thank you. Never again.
|
| I have committed these sins more than any other, and I'm mad as
| hell about it.
| devnullbrain wrote:
| > and the missing context is essential.
|
| Oh yes, I'd recommend everyone who uses the phrase reads the
| rest of the paper to see the kinds of optimisations that Knuth
| considers justified. For example, optimising memory accesses in
| quicksort.
| anymouse123456 wrote:
| Exactly!
|
| I wish Knuth would come out and publicly chastise the many
| decades of abuse this quote has enabled.
| trey-jones wrote:
| To be fair, I think human nature is probably a bigger
| culprit here than the quote. Yes, it was one of the first
| things told to me as a new programmer. No, I don't think it
| influenced very heavily how I approach my work. It's just
| another small (probably reasonable) voice in the back of my
| head.
| kalaksi wrote:
| 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 wrote:
| 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 wrote:
| >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.
| pydry wrote:
| 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 wrote:
| How would you have minimised migration costs for
| std::map?
| 9rx wrote:
| _> 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.
| lynndotpy wrote:
| Yep. If one is implementing quicksort for a library where it
| will be used and relied on, I'd sure hope they're optimizing
| it as much as they can.
| frereubu wrote:
| Totally agree. Out of this context, the word "premature" can
| mean too many things.
| aljgz wrote:
| In all honesty, this is one of the less abused quotes, and I
| have seen more benefit from it than harm.
|
| Like you, I've seen people produce a lot of slow code, but it's
| mostly been from people who would have a really hard time
| writing faster code that's less wrong.
|
| I hate slow software, but I'd pick it anytime over bogus
| software. Also, generally, it's easier to fix performance
| problems than incorrect behavior, especially so when the error
| has created data that's stored somewhere we might not have
| access to. But even more so, when the harm has reached the real
| world.
| anymouse123456 wrote:
| I don't believe there is any tension at all between fast and
| simple software.
|
| We can and should have both.
|
| This is a fraud, made up by midwits to justify their leaning
| towers of abstraction.
| embedding-shape wrote:
| User-facing, sure, nothing stopping us from doing "simple
| and fast" software. But when it comes to the code, design
| and architecture, "simple" is often at odds with "fast",
| and also "secure". Once you need something to be fast and
| secure, it often leads to a less simple design, because now
| you care about more things, it's kind of hard to avoid.
| ndriscoll wrote:
| IME doing application servers and firmware my whole
| career, simple and fast are usually the same thing, and
| "simple secure" is usually better security posture than
| "complex secure".
| embedding-shape wrote:
| Interesting, never done firmware, but plenty of backends
| and frontends. Besides the whole "do less and things get
| faster", I can't think of a single case where "simple"
| and "fast" is the same thing.
|
| And I'd agree that "simple secure" is better than
| "complex secure" but you're kind of side-stepping what I
| said, what about "not secure at all", wouldn't that lead
| to simpler code? Usually does for me, especially if you
| have to pile it on top of something that is already not
| so secure, but even when taking it into account when
| designing from ground up.
| ndriscoll wrote:
| Not really. `return 0` is the simplest program you could
| write, but it's not terribly useful. There's an
| underlying assumption that there's some
| purpose/requirement for the program to exist. Through
| that lens "secure" is just assumed as a requirement, and
| the simplest way to meet your requirements will usually
| still give you the fastest program too.
|
| "Do less and things get faster" is a very wide class of
| fixes. e.g. you could do tons of per-packet decision
| making millions of times per second for routing and
| security policies, or you could realize the answer
| changes slowly in time, and move that to upfront work,
| separating your control vs data processing, and generally
| making it _easier_ to understand. Or you could build your
| logic into your addressing /subnets and turn it into a
| simple mask and small table lookup. So your entire logic
| gets boiled down to a table (incidentally why I can't
| understand why people say ipv6 is complex. Try using
| ipv4! Having more bits for addresses is awesome!).
| MyHonestOpinon wrote:
| > "simple" is often at odds with "fast"
|
| Sort of. But if you keep the software simple, then it is
| easier to optimize the bottlenecks. You don't really need
| to make everything complicated to make it faster, just a
| few well selected places need to be refactored.
| gspr wrote:
| > I have seen more benefit from it than harm.
|
| Same. I, too, am sick of bloated code. But I use the quote as
| a reminder to myself: "look, the fact that you _could_ spend
| the rest of the workday making this function run in linear
| instead of quadratic time doesn 't mean you should - you have
| so many other tasks to tackle that it's better that you leave
| the suboptimal-but-obviously-correct implementation of this
| one little piece as-is for now, and return to it later if you
| need to".
| bko wrote:
| > Multiple generations of programmers have now been raised to
| believe that brutally inefficient, bloated, and slow software
| is just fine. There is no limit to the amount of boilerplate
| and indirection a computer can be forced to execute. There is
| no ceiling to the crystalline abstractions emerging from these
| geniuses. There is no amount of time too long for a JVM to
| spend starting.
|
| I think that's due to people doing premature optimization! If
| people took the quote to heart, they would be less inclined to
| increasing the amount of boilerplate and indirection.
| ummonk wrote:
| The boilerplate and indirection isn't done for performance
| YesThatTom2 wrote:
| I hear you, friend!
|
| While you were seeing those problems with Java at Google, I saw
| seeing it with Python.
|
| So many levels of indirection. Holy cow! So many unneeded
| superclasses and mixins! You can't reason about code if the
| indirection is deeper than the human mind can grasp.
|
| There was also a belief that list comprehensions were magically
| better somehow and would expand to 10-line monstrosities of
| unreadable code when a nested for loop would have been more
| readable and just as fast but because list comprehensions were
| fetishized nobody would stop at their natural readability
| limits. The result was like reading the run-on sentence you
| just suffered through.
| twoodfin wrote:
| Ignoring optimization opportunities until you see the profile
| only works when you actually profile!
|
| Profiling never achieved its place in most developers' core
| loop the way that compiling, linting, or unit testing did.
|
| How many real CI/CD pipelines spit out flame graphs alongside
| test results?
| pydry wrote:
| I usually defer this until a PM does the research to
| highlight that speed is a burning issue.
|
| I find 98% of the time that users are clamoring to get
| something implemented or fixed which isnt speed related so I
| work on that instead.
|
| When I do drill down what I tend to find in the flame graphs
| is that your scope for making performance improvements a user
| will _actually_ notice is bottlenecked primarily by I /O not
| by code efficiency.
|
| Meanwhile my less experienced coworkers will spot a nested
| loop that will never take more than a couple of milliseconds
| and demand it be "optimised".
| lokar wrote:
| Even at Google, the tendency is (or was when I was there),
| to only profile things that we know are consuming a lot of
| resources (or for sure will), or are hurting overall
| latency.
|
| Also the rule (quote?) says "speed hack", I don't think he
| is saying ignore runtime complexity totally, just don't go
| crazy with really complex stuff until you are sure you need
| it.
| Jensson wrote:
| That depends on which part of Google. I worked in the hot
| path of the search queries and there speed was extremely
| important for everything, they want to do so much there
| every single query and latency isn't allowed to go up.
| IshKebab wrote:
| The problem with ignoring performance is that you'll always
| end up with slow software that is awful to use but ticks
| all the feature boxes. As soon as someone comes along that
| is fast and nice people will switch to that.
|
| People don't ask for software to be fast and usable because
| it obviously should be. Why would they ask? They might
| _complain_ when it 's unusably slow. But that doesn't mean
| they don't want it to be fast.
| sph wrote:
| Another one from my personal experience: apply DRY principles
| (don't repeat yourself) the _third_ time you need something. Or
| in other words: you 're allowed to copy-and-paste the same
| piece of code in two different places.
|
| Far too often we generalise a piece of logic that we need in
| one or two places, making things more complicated for ourselves
| whenever they inevitably start to differ. And chances are very
| slim we will actually need it more than twice.
|
| Premature generalisation is the most common mistake that
| separates a junior developer from an experienced one.
| busfahrer wrote:
| Agreed, I think even Carmack advocates this rule
| cjs_ac wrote:
| DRY follows WET (Write Everything Twice).
| colechristensen wrote:
| Ehh, people who are really excited about DRY write unreadable
| convoluted code, where the bulk of the code is abstractions
| invented to avoid rewriting a small amount of code and unless
| you're very familiar with the codebase reasoning about what
| it actually does is a mystery because related pieces of
| functionality are very far away from each other.
| trey-jones wrote:
| DRY is not to avoid writing code (of any amount). DRY is a
| maintainability feature. "Unless you're very familiar with
| the code" you probably won't remember that you have to make
| this change in two places instead of one. DRY makes life
| easier for future you, and anyone else unfortunate to
| encounter (y)our mess.
| bluGill wrote:
| You are confusing DRY done as intended vs what DRY looks
| like in the real world to many people.
| colechristensen wrote:
| Making maintainable code is a good goal.
|
| DRY is one step removed from that goal and people use it
| to make very unmaintainable code because they confuse any
| repeated code with unmaintainability. (or their theory
| that some day we might want to repeat this code so we
| might as well pre-DRY it)
|
| The result is often a horrendous complex mess. Imagine a
| cookbook with a cookie recipe that resided on 47
| different pages (40 of which were pointers on where to
| find other pointers on where to find other pointers on
| where to find a step) in attempts to never write the same
| step twice in the whole book or your planned sequels in a
| 20 volume set.
| chuckadams wrote:
| It's almost like there's a "reasonable person" type of
| standard that's impossible to nail down in a general
| rule...
| colechristensen wrote:
| If you can describe a rule in one sentence it'll probably
| lead to as much trouble as it fixes.
|
| The problem is zealots. Zealotry doesn't work for
| indeterminate things that require judgement like "code
| quality" or "maintainability", but a simple rule like
| "don't repeat yourself" is easy for a zeal. They take a
| rule and shut down any argument with "because the rule!"
|
| If you're arguing about code quality and maintainability
| without one sentence rules then you actually have to make
| arguments. If the rule is your argument there's no
| discussion only dogma.
|
| As a result? Easy to distill rules spread fast, breed
| zealots, and result in bad code.
| matthewkayin wrote:
| I think we should not even generalize it down to a rule of
| three, because then you're outsourcing your critical thinking
| to a rule rather than doing the thinking yourself.
|
| Instead, I tend to ask: if I change this code here, will I
| always also need to change it over there?
|
| Copy-paste is good as long as I'm just repeating patterns. A
| for loop is a pattern. I use for loops in many places. That
| doesn't mean I need to somehow abstract out for loops because
| I'm repeating myself.
|
| But if I have logic that says that button_b.x = button_a.x +
| button_a.w + padding, then I should make sure that I only
| write that information down once, so that it stays consistent
| throughout the program.
| nostrademons wrote:
| The reason for the rule of thumb is because you don't
| _know_ whether you will need to change this code here when
| you change it there until you 've written several instances
| of the pattern. Oftentimes different generalizations become
| appropriate for N=1, N=2, N>=3 && N <= 10, N>=10 && N<=100,
| and N>=100.
|
| Your example is a pretty good one. In most practical
| applications, _you do not want to be setting button x
| coordinates manually_. You want to use a layout manager,
| like CSS Flexbox or Jetpack Compose 's Row or Java Swing's
| FlowLayout, which takes in a padding and a direction for a
| collection of elements and automatically figures out where
| they should be placed. But if you only have one button,
| this is overkill. If you only have two buttons, this is
| overkill. If you have 3 buttons, you should start to
| realize this is the pattern and reach for the right
| abstraction. If you get to 10 buttons, you'll realize that
| you need to arrange them in 2D as well and handle how they
| grow & shrink as you resize the window, and there's a good
| chance you need a more powerful abstraction.
| rkomorn wrote:
| > Instead, I tend to ask: if I change this code here, will
| I always also need to change it over there?
|
| IMO, this is the exact (and arguably only) question to ask.
| 9rx wrote:
| Critical thinkers understand that rules aren't written for
| critical thinkers; that they are written for beginners who
| don't yet have the necessary experience to be able to think
| critically.
| TeMPOraL wrote:
| I really like Casey Muratori's "[Semantic] Compression-
| oriented programming" - which is the philosophical backing of
| "WET" (Write Everything Twice) counterpart to DRY.
|
| https://caseymuratori.com/blog_0015
| trey-jones wrote:
| I think this is a reasonable rule of thumb, but there are
| also times that the code you are about to write a second time
| is extremely portable and can easily be made reusable (say
| less than 5 minutes of extra time to make the abstraction).
| In these cases I think it's worth it to go ahead and do it.
|
| Having identical logic in multiple places (even only 2) is a
| _big_ contributor to technical debt, since if you 're
| searching for something and you find it and fix it /once/ we
| often thing of the job as done. Then the "there is still a
| bug and _I already fixed that_ " confusion is avoided by
| staying DRY.
| andrewmutz wrote:
| You say that, but I've created plenty of production bugs
| because two different implementations diverge. Easier to
| avoid such bugs if we just share the implementation.
| bluGill wrote:
| I've also seen a lot of production bugs because two things
| that appeared to be a copy/paste where actually
| conceptually different and making them common made the
| whole much more complex trying to get common code to handle
| things that diverged even though they started from the same
| place.
| hackemmy wrote:
| This is so true. I have been burned by this more times than I
| can count. You see two functions that look similar, you
| extract a shared utility, and then six months later one of
| them needs a slightly different behavior and now you are
| fighting your own abstraction instead of just changing one
| line in a copy. The rule of three is a good default. Let the
| pattern prove itself before you try to generalize it.
| UncleMeat wrote:
| More critical in my mind is investigating the "inevitably
| start to differ" option.
|
| If two pieces of code use the same functionality by
| coincidence but could possibly evolve differently then don't
| refactor. Don't even refactor if this happens three, four, or
| five times. Because even if the code may be identical today
| the features are not actually identical.
|
| But if you have two uses of code that actually semantically
| identical and will assuredly evolve together then go ahead
| and refactor to remove duplication.
| Kye wrote:
| As always, xkcd:
|
| https://xkcd.com/1205/
|
| https://xkcd.com/974/
| tikhonj wrote:
| The rule of 3 is awful because it focuses on the wrong thing.
| If two instances of the same logic represent the same
| concept, they should be shared. If 10 instances of the same
| logic represent unrelated concepts, they should be
| duplicated.
|
| The goal is to have code that corresponds to a coherent
| conceptual model for whatever you are doing, and the
| resulting codebase should clearly reflect the design of the
| system. Once I started thinking about code in these terms, I
| realized that questions like "DRY vs YAGNI" were not
| meaningful.
| taneq wrote:
| > If two instances of the same logic represent the same
| concept, they should be shared. If 10 instances of the same
| logic represent unrelated concepts, they should be
| duplicated.
|
| Exactly.
| sph wrote:
| The devil's in the details, as usual. No rule should be
| followed to the letter, which is what the top comment was
| initially complaining about.
|
| Yet again, understanding when to follow a rule of thumb or
| not is another thing that separates the junior from the
| senior.
| miloignis wrote:
| Of course, the rule of 3 is saying that you often _can't
| tell_ what the shared concept between different instances
| is until you have at least 3 examples.
|
| It's not about copying _identical_ code twice, it 's about
| refactoring similar code into a shared function once you
| have enough examples to be able to see what the shared core
| is.
| imajoredinecon wrote:
| 3 just seems arbitrary in practice though. In my job we
| share code when it makes sense and don't when it doesn't,
| and that serves us just fine
| datsci_est_2015 wrote:
| But don't let the rule of 3 be an excuse for you to not
| critically assess the abstract concepts that your program
| is operating upon and within.
|
| I too often see junior engineers (and senior data
| scientists...) write code procedurally, with giant
| functions and many, many if statements, presumably
| because in their brain they're thinking about "1st I do
| this if this, 2nd I do that if that, etc".
| eyelidlessness wrote:
| I agree. And I think this also distills down to Rob Pike's
| rule 5, or something quite like it. If your design
| prioritizes modeling the domain's data, shaping algorithms
| around that model, it's usually trivial to determine how
| likely some "duplication" is operating on shared concepts,
| versus merely following a similar pattern. It may even help
| you refine the data model itself when confronted with the
| question.
| fauigerzigerk wrote:
| Agreed. DRY is a compression algorithm. The rule of 3 is a
| bad compression algorithm. Good abstraction is not
| compression at all.
| taneq wrote:
| "Once, twice, automate/abstract" is a good general rule but
| you have to understand that the thing you're counting isn't
| appearances in the source code, it's repetitions of the same
| logic _in the same context_. It's gotta _mean_ the same, not
| just look the same.
| krilcebre wrote:
| The instances should be based on the context. For example we
| had a few different API providers for the same thing, and
| someone refactored the separate classes into a single one
| that treats all of the APIs the same.
|
| Well, turns out that 3 of the APIs changed the way they
| return the data, so instead of separating the logic, someone
| kept adding a bunch of if statements into a single function
| in order to avoid repeating the code in multiple places. It
| was a nightmare to maintain and I ended up completely
| refactoring it, and even tho some of the code was repeated,
| it was much easier to maintain and accommodate to the API
| changes.
| Pxtl wrote:
| Depends on length and complexity, imho. If it's more than a
| line or two of procedure? Or involves anything
| counterintuitive? DRY at 2.
|
| Extract a method or object if it's something that feels
| conceptually a "thing" even if it has only one use. Most
| tools to DRY your code also help by providing a bit of
| encapsulation that do a great job of tidying things up to
| force you to think about "should I be letting this out of
| domain stuff leak in here?"
| mock-possum wrote:
| My rule of thumb is "when I have to make changes to this
| later, how annoying is it going to be to make the same change
| in multiple places?"
|
| Sometimes four or five doesn't seem too bad, sometimes two is
| too many
| moogly wrote:
| The D stands for "dependency", the R stands for "regret" and
| I'm not sure what the Y stands for yet.
| zer00eyz wrote:
| Yelling... it stands for yelling...
|
| Mostly at the massive switch statements and 1000 line's of
| flow control logic that end up embedded someplace where
| they really dont belong in the worst cases.
| mort96 wrote:
| IMO, the right way to think about DRY is to consider why a
| given piece of code would ever change.
|
| If you have two copies of some piece of code, and you can
| reasonably say that if you ever want to update one copy then
| you will almost certainly want to update the other copy as
| well, then it's probably a good idea to try to merge them and
| keep that logic in some centralized place.
|
| On the other hand, if you have three copies of the same piece
| of code, but they kind of just "happen to" be identical and
| it's completely plausible that any one of the copies will be
| modified in the future for reasons which won't affect the
| other copies, maybe keeping them separate is a good idea.
|
| And of course, it's sometimes worth it to keep two or more
| different copies which _do_ share the same "reason to
| change". This is especially clear when you have the copies in
| different repositories, where making the code "DRY" would
| mean introducing dependencies between repositories which has
| its own costs.
| bsza wrote:
| It's not how many times, it's what you do about it. DRY
| doesn't mean you have to make abstractions for everything. It
| means you don't repeat yourself. That is, if two pieces of
| code are identical, chances are one of them shouldn't exist.
| There are a lot of simple ways you might be able to address
| that, starting from the most obvious one, which is to just
| literally delete one of them. Abstraction should be about the
| last tool you reach for, but for most people it's
| unfortunately the first.
| noufalibrahim wrote:
| I had a situation where we need to implement a protocol. The
| spec was fairly decent but the public implementations of the
| other end were slightly non compliant which necessitated
| special casing. Plus multiple versions etc.
|
| An expensive consultant suggested creating pristine
| implementation and then writing a rule layer that would
| modify things as needed and deploying the whole thing as a
| pile of lamdba functions.
|
| I copy pasted the protocol consumer file per producer and
| made all the necessary changes with proper documentation and
| mocks. Got it working quickly and we could add new ones
| without affecting.
|
| If I'd try to keep it DRY, i think it would be a leaky mess.
| dwb wrote:
| Totally agree. I've see that quote used to justify wilfully
| ignoring basic performance techniques. Then people are
| surprised when the app is creaking exactly due to the lack of
| care taken earlier. I would tend to argue the other way most of
| the time: a little performance consideration goes a long way!
|
| Maybe I've had an unrepresentative career, but I've never
| worked anywhere where there's much time to fiddle with
| performance optimisations, let alone those that make the
| code/system significantly harder to understand. I expect that's
| true of most people working in mainstream tech companies of the
| last twenty years or so. And so that quote is basically never
| applicable.
| pjc50 wrote:
| Slow code is more of a project management problem. Features are
| important and visible on the roadmap. Performance usually isn't
| until it hits "unacceptable", which may take a while to feed
| back. That's all it is.
|
| (AI will probably make this worse as well, having a bloat
| tendency all of its own)
| lowmagnet wrote:
| I always point out the operational word is "premature".
| dominotw wrote:
| > I have lived the absolute nightmares that evolve from the
| willful misunderstanding of this quote.
|
| how do you know which code was written using this quote in
| mind.
| BoneShard wrote:
| He doesn't know, but that quote makes for a cool talking
| point. Software is slow or bloated because of budget,
| deadlines, and skill levels - not because of a quote.
| globular-toast wrote:
| So you're saying people have misunderstood "premature
| optimisation is the root of all evil" as "optimisation is the
| root of all evil"?
|
| I don't think you can blame this phrase if people are going to
| drop an entire word out of an eight word sentence. The very
| first word, no less.
| bluGill wrote:
| Don't confuse premature pessimization for the warnings against
| premature optimization.
|
| I can write bubble sort, it is simple and I have confidence it
| will work. I wrote quicksort for class once - I turned in
| something that mostly worked but there were bugs I couldn't fix
| in time (but I could if I spent more time - I think...)
|
| However writing bubble sort is wrong because any good language
| has a sort in the standard library (likely timsort or something
| else than quicksort in the real world)
| taneq wrote:
| > I have lived the absolute nightmares that evolve from the
| willful misunderstanding of this quote.
|
| Then the quote wasn't the problem. The wilful misunderstanding
| was the problem.
| koliber wrote:
| Picking the starting point is very important. "optimization" is
| the process of going from that starting point to a more
| performant point.
|
| If you don't know enough to pick good starting points you
| probably won't know enough to optimize well. So don't optimize
| prematurely.
|
| If you are experienced enough to pick good starting points,
| still don't optimize prematurely.
|
| If you see a bad starting point picked by someone else, by all
| means, point it out if it will be problematic now or in the
| foreseeable future, because that's a bug.
| JTbane wrote:
| Anyone else feel like bloat is usually not an algorithmic
| problem, but rather a library or environment issue most of the
| time?
| wavemode wrote:
| I don't think the quote itself is responsible for any of that.
|
| It's true that premature optimization (that is, optimization
| before you've measured the software and determined whether the
| optimization is going to make any real-world difference) is
| bad.
|
| The reality, though, is that most programmers aren't grappling
| with whether their optimizations are premature, they're
| grappling with whether to optimize at all. At most companies,
| once the code works, it ships. There's little, if any, time
| given for an extra "optimization" pass.
|
| It's only after customers start complaining about performance
| (or higher-ups start complaining about compute costs) that
| programmers are given any time to go through and optimize
| things. By which point refactoring the code is now much harder
| than it wouldn've been originally.
| Megranium wrote:
| Huh, I've always understood that quote very differently, with
| emphasis on "premature" ... not as in, "don't optimize" but
| more as in "don't optimize before you've understood the
| problem" ... or, as a CS professor of mine said "Make it work
| first, THEN make it work fast" ...
| DarkCrusader2 wrote:
| well you see, in corporate (atleast in big tech), this is
| usually used as a justification to merge inefficient code (we
| will optimize it later). That later never comes, either the
| developers/management moves on or the work item never gets
| prioritized. That is until the bad software either causes
| outages or customer churn. Then it is fixed and shown as high
| impact in your next promo packet.
| lokar wrote:
| And if you know in advance that a function will be in the
| critical path, and it needs to perform some operation on N
| items, and N will be large, it's not premature to consider
| the speed of that loop.
| lokar wrote:
| Another thought: many (most?) of these "rules" were before
| widespread distributed computing. I don't think Knuth had
| in mind a loop that is reading from a database at 100ms
| each time.
|
| I've seen people write some really head shaking code that
| makes remote calls in a loop that don't actually depend on
| each other. I wonder to what extend they are thinking
| "don't bother with optimization / speed for now"
| rob74 wrote:
| If you really have a loop that is reading from a database
| at 100ms each time, that's not because of not having
| optimized it prematurely, that's just stupid.
| lokar wrote:
| And yet... :)
|
| I think there is just a current (I've seen it mostly in
| Jr engineers) that you should just ignore any aspect of
| performance until "later"
| lokar wrote:
| and, I guess, context does matter. If you need to make 10
| calls to gather up some info to generate something, but
| you only need to do this once a day, or hour, and if the
| whole process takes a few seconds that's fine, I could
| see the argument that just doing the calls one at a time
| linearly is simpler write/read/maintain.
| heliumtera wrote:
| Got it. What about initiating a 800mb image on a CPU
| limited virtual machine that THEN hits a database, before
| responding to a user request on a 300ms roundtrip? I
| think we need a new word to describe the average
| experience, stupidity doesn't fit.
| patrickthebold wrote:
| Reminds me of this quote which I recently found and like:
|
| > look, I'm sorry, but the rule is simple: if you made
| something 2x faster, you might have done something smart
| if you made something 100x faster, you definitely just
| stopped doing something stupid
|
| https://x.com/rygorous/status/1271296834439282690
| kstrauser wrote:
| First, I agree with what you're saying.
|
| But second, I'd remove "optimization" from considering
| here. The code you're describing isn't _slow_ , it's
| _bad_ code that also happens to be slow. Don 't write bad
| code, ever, if you can knowingly avoid it.
|
| It's OK to write good, clear, slow code when correctness
| and understandability is more important that optimizing
| that particular bit. It's not OK to write boneheaded
| code.
|
| (Exception: After you've written the working program, it
| turns out that you have all the information to make the
| query once in one part of the broader program, but don't
| have all the information to make it a second time until
| flow reaches another, decoupled part of the program. It
| may be the lesser evil to do that than rearrange the
| entire thing to pass all the necessary state around,
| although you're making a deal with the devil and pinky
| swearing never to add a 3rd call, then a 4th, then a 5th,
| then...)
| redbar0n wrote:
| Just remember Rob Pike's 1st rule: don't assume where
| bottlenecks will occur, but verify it.
| ummonk wrote:
| I've worked on optimizing modern slow code. Once you
| optimize a few bottlenecks it turns out it's very hard to
| optimize because the rest of the time is spread out over
| the whole code without any small bottlenecks and it's all
| written in a slow language with no thought for
| performance.
| senfiaj wrote:
| From my understanding you still need to care care about the
| algorithms and architecture. If N is sufficiently large,
| you should pick O(N) algorithm over O(N^2). But usually
| there is a tradeoff, simple code (or hiding something
| behind some abstraction) might be easier to understand and
| maintain, but it might work slower with large input data
| and vice versa. I would rather write code that will be
| easier to optimize if there is some bottleneck than to
| optimize it overagressivelly. Also, different code needs
| different kind of optimization. Sometimes the code might be
| more IO heavy (disk / DB or network), for this type of
| code, the IO operation planning and caching is more
| critical than the optimization of the raw CPU time.
| Sometimes the input is too small to have any significant
| performance effects, and, what's paradoxical, choosing
| smarter algorithms might even hurt performance (alongside
| the maintanability). For example, for 10 - 100 items a
| simple linear scan in an array might be faster than using a
| O(log n) binary search tree. It's also well known that
| faster executable code (regardless of being hand written,
| machine generated, high level or machine code) usually has
| larger size (mostly because it's more "unrolled",
| duplicated and more complex when advanced algorithms are
| used). If you optimize the speed everywhere, the binary
| size tends to increase, causing more cache misses, which
| might hurt the performance more than improve. This is why
| some profiling is often needed for large software than
| simply passing O3.
| vbezhenar wrote:
| We will optimize it later, we don't have time for that right
| now, it seems it works fast enough for our needs right now.
|
| "Later" never comes and all critical performance issues are
| either ignored, hot-patched externally with caches of various
| quality or just with more expensive hardware.
| Nemi wrote:
| While what you say is often true, it is a different problem
| and does not change the fact of the prior posters.
| zygentoma wrote:
| My favourite quote for that is:
|
| Broken gets fixed, but crappy stays forever
| mort96 wrote:
| Plenty of people seem to understand it as, "don't even
| _think_ about performance until someone has made a strong
| enough business case that the performance is sufficiently bad
| as to impact profits ".
| ekropotin wrote:
| IDK if it can be applied in all situations.
|
| Sometimes, especially when it comes to distributed systems,
| going from working solution to fast working solution requires
| full blown up redesign from scratch.
| bdangubic wrote:
| > Make it work first, THEN make it work fast
|
| 1. I have seen too many "make it work first" that ended up
| absolute shitshow that was notoriously difficult to do
| anything with. You _can_ build the software right the first
| time
|
| 2. The "fast" part is what I think too many people are
| focusing on and in my experience the "THEN" part is always
| missing resources utilization and other types of inefficiency
| that are not necessarily related to speed. I have seen
| absolute messes of software that work _really_ fast
| rco8786 wrote:
| Ditto here
| artyom wrote:
| I agree with you. "Premature" is the keyword. Bloated
| software is the result of not having the intention to
| optimize it at all.
| divan wrote:
| > generations of programmers have now been raised to believe
| that brutally inefficient, bloated, and slow software is just
| fine.
|
| I believe people don't think about Knuth when they choose to
| write app in Electron. Some other forces might be at play here.
| imjonse wrote:
| I was a bit worried you are paraphrasing Rob Pike, but no, he
| actually agrees with that Knuth quote.
|
| I am almost certain that people building bloated software are
| not willfully misunderstanding this quote; it's likely they
| never heard about it. Let's not ignore the relevance of this
| half a century old advice just because many programmers do not
| care about efficiency or do not understand how computers work.
| Premature optimization is exactly that, the fact that is
| premature makes it wrong, regardless if it's about GOTO
| statements in the 70s or a some modern equivalent where in the
| name of craft or fun people make their apps a lot more complex
| than they should be. I wouldn't be surprised if some of the
| brutally inefficient code you mention was so because people
| optimized prematurely for web-scale and their app never ever
| needed those abstractions and extra components. The advice
| applies both to hackers doing micro-optimizations and
| architecture astronauts dreaming too big IMHO.
| IshKebab wrote:
| No I've definitely heard plenty of people use this as some
| kind of inarguable excuse to not care about performance.
| Especially if they're writing something in Python that should
| really be not super slow. "It's fine! Premature optimisation
| and all that. We'll optimise it later."
|
| And then of course later is too late; you can't optimise most
| Python.
| lynndotpy wrote:
| I think the bigger problem is that "Premature optimization is
| the root of all evil" is a statement made by software engineers
| to feel more comfortable in their shortcomings.
|
| That's not to bemoan the engineer with shortcomings. Even the
| most experienced and educated engineer might find themself
| outside their comfort zone, implementing code without the
| ability to anticipate the performance characteristics under the
| hood. A mental model of computation can only go so far.
|
| Articulated more succinctly, one might say "Use the profiler,
| and use it often."
| trgn wrote:
| > Multiple generations of programmers have now been raised to
| believe that brutally inefficient, bloated, and slow software
| is just fine
|
| 100%
| trgn wrote:
| A lot of developers get enamored by fetishes. Just one example,
| because it's one i always struggle to vanquish in any of my
| teams.
|
| Devs are obsessed with introducing functional-style constructs
| everywhere, just for the sake of it. FP is great for some
| classes of software, but baseline crufty for anything that
| requires responsiveness (front-ends basically), let alone
| anything at real interactive speeds (games, geo-software, ...)
|
| The "premature optimization" quote is then always used as a way
| to ignore that entire code paths will be spamming the heap with
| hundreds of thousands of temporary junk, useless lexical
| scopes, and so forth. Writing it lean the first time is never
| considered, because of adherence to these fetishes (mutability
| is bad, oo is bad, loops lead to off-by-one errors, ...). It's
| absolutely exhausting to have these conversations, it's always
| starting from the ground up and these quotes like "premature
| optimization is the root of all evil" are only used as
| invocations to ward of criticism.
| 01100011 wrote:
| This is the sort of pontifical statement that old guys like me
| tend to make which is strictly wrong but also contains a lot of
| wisdom.
|
| Yes, software is bloated, full of useless abstractions and bad
| design. You kids(well, anyone programming post 1980, so myself
| included) should be ashamed. Also let's not forget that those
| abstractions helped us solve problems and our friends in
| silicon valley(ok that no longer makes sense but imagine if
| SillyValley still just made HW) covered our mistakes. But yeah,
| we write crap a lot of the time.
|
| But as other folks have said, it doesn't mean "don't optimize."
|
| I've always used my own version of the phrase, which is: "Don't
| be stupid." As in, don't do dumb, expensive things unless you
| need to for a prototype. Don't start with a design that is far
| from optimal and slow. After profiling, fix the slow things.
| I'm pretty sure that's what most folks do on some level.
| whatever1 wrote:
| At least before the LLM world you would have to trade money
| (aka more compute) for time to market. What is the point of
| spending a single second optimizing a query when your database
| has 10 users?
|
| Of course today this has changed. You can have multiple agents
| working on micro optimizing everything and have the pie and eat
| it too.
| pphysch wrote:
| It has less to do with a quote and more to do with CS education
| (and the market) rewarding minimal functionality over
| performance, security, fault-tolerance, etc.
|
| The average university CS student in USA (and India I presume)
| is taught to "hack it" at any cost, and we see the results.
| dblohm7 wrote:
| I too learned this the hard way, via a supposedly concurrent
| priority queue that did quadratic-time work while holding a
| lock over the entire thing. I was told that "premature
| optimization is the root of all evil."
|
| Sorry, folks, but that's just an excuse to make dumb choices.
| Premature _micro_optimization is the root of all evil.
|
| EDIT: It was great training for when I started working on
| browser performance, though!
| dblohm7 wrote:
| And if I may add a corollary: Measurement doesn't need to be
| held off until the end of the project! Start doing it as soon
| as you can!
| jayd16 wrote:
| This discussion kind of irks me. I just read these posts as:
| "The quote saying A is bad. Actually it said A all along!"
|
| It's just complaining about others making a different value
| judgement for what is a worthwhile optimization. Hiding behind
| the 'true meaning of the quote' is pointless.
| andoando wrote:
| As someone currently writing 16-18 tables all with common
| definition, and crud, Id like some abstraction
| didgetmaster wrote:
| I agree. Faster hardware or horizontal scaling on distributed
| cloud environments can mask the problem; but it certainly
| doesn't solve the problem of bloated, inefficient software.
|
| While it might not be necessary to spend hours fine-tuning
| every function; code optimization should be the mindset of
| every programmer no matter what they are coding.
|
| How many fewer data centers would we need if all that software
| running in them was more efficient?
|
| https://didgets.substack.com/p/finding-and-fixing-a-billion-...
| rixed wrote:
| I wish we lived in a world where quotes could be that powerful.
| But I'm afraid in reality this quote, like any other, is just
| used as a justification after the fact.
|
| Actually, I do not believe devs are to blame, or that CS
| education is to blame; I believe that's an unfortunate law of
| society that complexity piles up faster than we can manage it.
| Of course the economic system rewards shiping today at the
| expense of tomorrow's maintenance, and also rewards splitting
| systems in seemingly independent subsystems that are simpler in
| isolation but results in a more complex machinery (cloud,
| microservices...)
|
| I'm even wondering if it's not a more fundamental law than
| that, because adding complexity is always simpler than removing
| it, right? Kind of a second law of termodynamic for code.
| Someone wrote:
| > From his 1974 paper, "Structured Programming with go to
| Statements":
|
| > He was talking about using GOTO statements in C.
|
| I don't think he was talking about C. That paper is from
| December 1974, and (early) C is from 1972, and "The UNIX Time-
| Sharing System" (https://dsf.berkeley.edu/cs262/unix.pdf) is
| from July 1974, so time wise, he could have known C, but AFAICT
| that paper doesn't mention C, and the examples are PL/I or
| (what to me looks like) pseudocode, using ':=' for assignment,
| 'if...fi' and 'while...repeat' for block, 'go to' and not C's
| 'goto', etc.
| Shawn19s83 wrote:
| surprised this isn't talked about more
| tasuki wrote:
| The first four are kind of related. For me the fifth is the
| important - and oft overlooked - one:
|
| > Data dominates. If you've chosen the right data structures and
| organized things well, the algorithms will almost always be self-
| evident. Data structures, not algorithms, are central to
| programming.
| ta20211004_1 wrote:
| Can't agree more on 5. I've repeatedly found that any really
| tricky programming problem is (eventually) solved by iterative
| refinement of the data structures (and the APIs they expose / are
| associated with). When you get it right the control flow of a
| program becomes straightforward to reason about.
|
| To address our favorite topic: while I use LLMs to assist on
| coding tasks a lot, I think they're very weak at this. Claude is
| much more likely to suggest or expand complex control flow logic
| on small data types than it is to recognize and implement an
| opportunity to encapsulate ideas in composable chunks. And I
| don't buy the idea that this doesn't matter since most code will
| be produced and consumed by LLMs. The LLMs of today are much more
| effective on code bases that have already been thoughtfully
| designed. So are humans. Why would that change?
| zer00eyz wrote:
| > refinement of the data structures (and the APIs they expose /
| are associated with)
|
| I think rule 5 is often ignored by a lot of distributed
| services. Where you have to make several calls, each with their
| own http, db and "security" overhead, when one would do. Then
| these each end up with caching layers because they are "slow"
| (in aggregate).
| nostrademons wrote:
| If you're doing it right, you start with a centralized
| service; get the product, software architecture, and data
| flows right while it's all in one process; and then
| distribute along architectural boundaries when you need to
| scale.
|
| Very few software services built today are doing it right.
| Most assume they need to scale from day one, pick a
| technology stack to enable that, and then alter the product
| to reflect the limitations of the tech stack they picked.
| Then they wonder why they need to spend millions on sales and
| marketing to convince people to use the product they've
| built, and millions on AWS bills to scale it. But then, the
| core problem was really that their company did not need to
| exist in the first place and only does because investors
| insist on cargo-culting the latest hot thing.
|
| This is why software sucks so much today.
| skeeter2020 wrote:
| >> If you're doing it right, you start with a centralized
| service; get the product, software architecture, and data
| flows right while it's all in one process; and then
| distribute along architectural boundaries when you need to
| scale.
|
| I'll add one more modification if you're like me (and
| apparently many others): go too far with your distribution
| and pull it back to a sane (i.e. small handful) number of
| distributed services, hopefully before you get too far down
| the implementation...
| alain94040 wrote:
| Agreed, in my experience, rule 5 should be rule 1. I think I
| also heard it said (paraphrased) as "show we your code and I'll
| be forever confused, show me your database schema and
| everything will become obvious".
|
| Having implemented my shared of highly complex high-performance
| algorithms in the past, the key was always to figure out how to
| massage the raw data into structures that allow the algorithm
| to fly. It requires both a decent knowledge of the various
| algorithm options you have, as well as being flexible to see
| that the data could be presented a different way to get to the
| same result orders of magnitude faster.
| skeeter2020 wrote:
| I have seen a huge decline in data first over the past
| decade-plus; maybe related to a lot more pragmatic training
| where code-first and abstraction helped you go faster,
| earlier but I definitely came of age starting with the schema
| and there are an awful lot of problems & systems that
| essentially are UI and functions on top of the schema.
| danielmarkbruce wrote:
| UI + functions on top of schema if you've designed the
| schema well. Otherwise, it's a whole other thing.
| beachy wrote:
| I think you are referring to:
|
| "Show me your flowchart and conceal your tables, and I shall
| continue to be mystified. Show me your tables, and I won't
| usually need your flowchart; it'll be obvious." -- Fred
| Brooks, The Mythical Man Month (1975)
| eikenberry wrote:
| I don't think they were ever meant to be in order of
| importance.
| dasil003 wrote:
| These rules aged well overall. The only change I would make these
| days is to invert the order.
|
| Number 5 is timeless and relevant at all scales, especially as
| code iterations have gotten faster and faster, data is all the
| more relevant. Numbers 4 and 3 have shifted a bit since data
| sizes and performance have ballooned, algorithm overhead isn't
| quite as big a concern, but the simplicity argument is relevant
| as ever. Numbers 2 and 1 while still true (Amdahl's law is a
| mathematical truth after all), are also clearly a product of
| their time and the hard constraints programmers had to deal with
| at the time as well as the shallowness of the stack. Still good
| wisdom, though I think on the whole the majority of programmers
| are less concerned about performance than they should be,
| especially compared to 50 years ago.
| treetalker wrote:
| I'm not a skilled programmer (but would like to be someday).
| Would someone kindly resolve what appears to me to be a
| contradiction between the following?
|
| 1(a) Torvalds: "Bad programmers worry about the code. Good
| programmers worry about data structures and their relationships."
|
| 1(b) Pike Rule 5: "Data dominates. If you've chosen the right
| data structures and organized things well, the algorithms will
| almost always be self-evident. Data structures, not algorithms,
| are central to programming."
|
| -- versus --
|
| 2. Perlis 2: "Functions delay binding; data structures induce
| binding. Moral: Structure data late in the programming process."
|
| ---
|
| Ignorant as I am, I read these to advise that I ought to put data
| structures centrally, first, foremost -- but not until the end of
| the programming process.
| colechristensen wrote:
| That is indeed contradictory and what those things say.
|
| Good structure comes from exploring until you understand the
| problem well AND THEN letting data structure dominate.
| foltik wrote:
| Afaict Perlis is more saying not to expose data layout in the
| boundaries between abstractions, rather to keep them pure and
| functional.
|
| So not really a contradiction, just Perlis talking about the
| functional shell and Torvalds/Pike talking about the imperative
| core.
| zweifuss wrote:
| When you explore a problem, use Python and
| lists/sets/dictionaries/JSON. Wait with types and specific data
| structures till you have understanding. Speed of development
| over speed of execution.
|
| When you know what and how to build commit to good data
| structures. Do the types, structs, classes, Trie, CRDTs, XML,
| Protobuf, Parquet and whatnot where apropriate. Instrument your
| program. The efficiency of the final product counts.
| dkarl wrote:
| I think it's fine and generous that he credited these rules to
| the better-known aphorisms that inspired them, but I think his
| versions are better, they deserve to be presented by themselves,
| instead of alongside the mental clickbait of the classic
| aphorisms. They preserve important context that was lost when the
| better-known versions were ripped out of their original texts.
|
| For example, I've often heard "premature optimization is the root
| of all evil" invoked to support opposite sides of the same
| argument. Pike's rules are much clearer and harder to interpret
| creatively.
|
| Also, it's amusing that you don't hear this anymore:
|
| > Rule 5 is often shortened to "write stupid code that uses smart
| objects".
|
| In context, this clearly means that if you invest enough mental
| work in designing your data structures, it's easy to write simple
| code to solve your problem. But interpreted through an OO
| mindset, this could be seen as encouraging one of the classic
| noob mistakes of the heyday of OO: believing that your code could
| be as complex as you wanted, without cost, as long as you hid the
| complicated bits inside member methods on your objects. I'm
| guessing that "write stupid code that uses smart objects" was a
| snappy bit of wisdom in the pre-OO days and was discarded as
| dangerous when the context of OO created a new and harmful way of
| interpreting it.
| zemo wrote:
| > but I think his versions are better, they deserve to be
| presented by themselves, instead of alongside the mental
| clickbait of the classic aphorisms
|
| keeping the historical chain of thinking alive is good,
| actually
| Matthyze wrote:
| "mental clickbait of the classic aphorisms" is one way to
| phrase 'attribution"
| mcdonje wrote:
| Very performance focused. Could more accurately be 5 rules of
| perf. Good list, though.
| _philipalan wrote:
| CS Unc remains un-chopped.
| ajpaulson wrote:
| I think I'm going to copy and paste this directly into my
| AGENTS.md file!
| d_burfoot wrote:
| I don't disagree with these principles, but if I wanted to
| compress all my programming wisdom into 5 rules, I wouldn't spend
| 3 out of the 5 slots on performance. Performance is just a
| component of correctness : if you have a good methodology to
| achieve correctness, you will get performance along the way.
|
| My #1 programming principle would be phrased using a concept from
| John Boyd: make your OODA loops fast. In software this can often
| mean simple things like "make compile time fast" or "make sure
| you can detect errors quickly".
| patwolf wrote:
| These rules apply equally well to system architecture. I've been
| trying to talk our team out of premature optimization (redis
| cluster) and fancy algorithms (bloom filters) to compensate for
| poor data structures (database schema) before we know if
| performance is going to be a problem.
|
| Even knowing with 100% certainty that performance will be subpar,
| requirements change often enough that it's often not worth the
| cost of adding architectural complexity too early.
| bob1029 wrote:
| > Even knowing with 100% certainty that performance will be
| subpar
|
| I think there is value in attempting to do something the "wrong
| way" on purpose to some extent. I have walked into many
| situations where I was beyond convinced that the performance of
| something would suck only to be corrected harshly by the
| realities of modern computer systems.
|
| Framing things as "yes, I know the performance is definitely
| not ideal in this iteration" puts that monkey in a proper cage
| until the next time around. If you don't frame it this way up
| front, you might be constantly baited into chasing the
| performance monkey around. Its taunts can be really difficult
| to ignore.
| sayYayToLife wrote:
| I suppose this makes me feel a little bit better about a multi-
| month process that ended up requiring the eight Queens problem.
|
| That said management did not quite understand. They thought that
| I should have known about the bottleneck (Actually I did but I
| was told not to prematurely optimize)
|
| I end up writing the program three times, the final solution was
| honestly beautiful.
|
| Management was not happy. The customer was happy.
| ekjhgkejhgk wrote:
| Uuuh doesn't look good that you claim something is important
| enough to be in your top 5, but then misattribute it.
| thecodemonkey wrote:
| Running the same codebase for 10+ years with a small team is what
| finally made me fully internalize these rules.
|
| I've always been a KISS/DRY person but over a decade there are
| plenty of moments where you're tempted to reach for a fancier
| database or rewrite something in a trendier stack. What's
| actually kept things running well at scale is boring, known
| technologies and only optimizing in the places where it actually
| matters.
|
| We wrote our principles down recently and it basically just reads
| like Pike's rules in different words: https://www.geocod.io/code-
| and-coordinates/2025-09-30-develo...
| andxor wrote:
| Great gonna add these to my CLAUDE.md /s
| HardCodedBias wrote:
| Heretical opinion:
|
| I think that Rob Pike was far more of a wordcel than a shape
| rotator for a famous computer scientist (which historically were
| very much on the shape rotator side).
| pdpi wrote:
| There's an important property that emerges from rules 3 and 4 --
| because the simple algorithm is easier to implement correctly,
| you can test the fancy algorithm for correctness by comparing its
| output to the simple one.
| publicdebates wrote:
| "Rule 6: Don't waste time on syntax highlighting unless you're
| incompetent."
| OpenDQV wrote:
| Golden rules for sure!
| yandrypozo wrote:
| does _a speed hack_ mean adding time.Sleep() for testing? or it's
| something else?
| possiblydrunk wrote:
| Optimization usually trades complexity for speed. Complexity
| hinders debugging and maintenance. Don't optimize unless you have
| to and not before you know where the bottleneck is.
| Straightforward common sense advice as long as hardware is not
| persistently constraining.
| TimLeland wrote:
| Take a look at the page title. I guess he didn't follow his own
| rules for this 100-line HTML file
|
| <title> <h1>Rob Pike's 5 Rules of Programming</h1> </title>
| BTAQA wrote:
| Rule 5 is the one that took me longest to internalize. Coming
| from frontend development into building a full product with a
| real database, I kept reaching for complex query logic when the
| real fix was just restructuring the data. Once the schema was
| right the queries became obvious. Brooks was right 50 years ago
| and it's still true.
| netbioserror wrote:
| This resonates as true, as long as the fundamentals of your tools
| are there. Picking interpreted languages or browsers as targets
| shoots you in the foot and sets you magnitudes behind when
| performance starts to matter. But if you're using a native-
| compiled language with value- and move-semantics, immutable data,
| and a composable type system, it's shocking how easy it can be to
| write obvious, maintainable, fast programs that perform under
| pressure, even when you're not being clever.
|
| Thankfully newer languages like Nim, Odin, and Swift lean hard
| into value semantics. They drastically reduce the cost of
| focusing on data structures and writing obvious algorithms. Then,
| when bottlenecks appear, you can choose to opt into fine-tuning.
| fogzen wrote:
| Rule 5 should be rule 1.
| SomaticPirate wrote:
| How quaint. I hope Claude/Codex reads this since from what I've
| heard here I'm not likely to need this rules anymore /s I am
| curious if anyone has attempted to use codex/claude with
| something like this in the prompt
| sneedenheimer wrote:
| Given that Rob Pike seems to think having a shell script that
| uses tar is better than having a `-r` flag for cp [1], I wouldn't
| give much weight to his philosophy of programming :P.
|
| [1]: https://wiki.c2.com/?WhatIsNotInPlanNine
| 01100011 wrote:
| Rule 3 gets me into trouble with CS majors a lot. I'm an EE by
| education and entered into SW via the bottom floor(embedded
| C/ASM) so it was late in my career before I knew the formal
| definition of big-O and complexity.
|
| For most of my career, sticking to rule 3 made the most sense.
| When the CS major would be annoying and talk about big-O they
| usually forgot n was tiny. But then my job changed. I started
| working on different things. Suddenly my job started sounding
| more like a leetcode interview people complain about. Now n
| really is big and now it really does matter.
|
| Keep in mind that Rob Pike comes from a different era when
| programming for 'big iron' looked a lot more like programming for
| an embedded microcontroller now.
| SoftTalker wrote:
| My father did some programming in Fortran and Assembly of
| various flavors. He was always partial to lookup tables where
| they could replace complicated conditionals or computations.
| Memory was precious in his day but it could still be worth it
| if your program did something repeatedly (which most do).
| kevincox wrote:
| I actually disagree with Rule 3! While numbers are usually
| small being fast on small cases generally isn't as important as
| performing acceptably on large cases. So I prefer to take the
| better big-O so that it doesn't slow down unacceptably on real-
| world edge-case stresses. (The type of workloads that the devs
| often don't experience but your big customers will.)
|
| Of course there is a balance to this, the engineering time to
| implement both options is an important consideration. But given
| both algorithms are relatively easy to implement I will default
| to the one that is faster at large sizes even if it is slower
| at common sizes. I do suspect that there is an implicit
| assumption that "fancy" algorithms take longer and are harder
| to implement. But in many cases both algorithms are in the
| standard library and just need to be selected. If this post
| focused on "fancy" in terms of actual time to implement rather
| than speed for common sizes I would be more inclined to agree
| with it.
|
| I wrote an article about this a while back:
| https://kevincox.ca/2023/05/09/less-than-quadratic/
| Jensson wrote:
| Rule 3 was true 1989, back then computers were so slow and
| had barely any ram so most things you did only was reasonable
| for small number of inputs. Today we almost always have large
| amounts of inputs so its different.
| danielmarkbruce wrote:
| This very much depends on where you work... and basically
| isn't true for most people. It's extremely true for some
| people.
| cjwoodall wrote:
| Rule 3 is still very much real. Fancy fast algorithms
| often have other trade-offs. The best algorithm for the
| job is the one that meets all requirements well... Big-O
| is one aspect, data is another, determinism of the
| underlying things that are needed (dynamic memory
| allocation, etc) can be another.
|
| It is important to remember that the art of sw
| engineering (like all engineering) lives in a balance
| between all these different requirements; not just in
| OPTIMIZE BIG-O.
| danielmarkbruce wrote:
| Sure but the default (and usually correct) assumption
| when working at google (as an example) is basically "all
| numbers are big", so you you have to cluey about
| algorithms and data structures and not default to brute
| forcing something.
|
| At 99% of shops it should be the other way around .
| jltsiren wrote:
| Even when you are working with large numbers, most
| numbers are usually small. Most of the code is probably
| not dealing with the large things, and a large thing may
| consist of a large number of instances that are
| individually small.
|
| I've personally found it useful to always have concrete
| numbers in mind. An algorithm or data structure designed
| for N will probably be fine for N/10 and 10N, but it will
| often be inefficient for N/1000 or 1000N.
| grogers wrote:
| Well it is hedged with the word "fancy". I think a charitable
| reading is to understand the problem domain. If N is always
| small then trying to minimize the big-O is just showing off and
| likely counterproductive in many ways. If N is large, it might
| be a requirement.
|
| Most people don't need FFT algorithm for multiplying large
| numbers, Karatsuba's algorithm is fine. But in some domains the
| difference does matter.
|
| Personally I usually see the opposite effect - people first
| reach for a too-naive approach and implement some O(n^2)
| algorithm where it wouldn't have even been more complex to
| implement something O(n) or O(n log n). And n is almost always
| small so it works fine, until it blows up spectacularly.
| bartread wrote:
| > Personally I usually see the opposite effect - people first
| reach for a too-naive approach and implement some O(n^2)
| algorithm where it wouldn't have even been more complex to
| implement something O(n) or O(n log n). And n is almost
| always small so it works fine, until it blows up
| spectacularly.
|
| Same. People solve in ways that are very obviously going to
| cause serious problems in only a few short weeks or months
| and it's endlessly frustrating. If you're building a
| prototype, fine, but if you're building for production, very
| far from fine.
|
| Most frustrating because often there's next to no cost in
| selecting and implementing the correct architecture, domain
| model, data structure, or algorithm up front.
| big-chungus4 wrote:
| Idk about rule 1, in my experience it's usually pretty clear
| which part of code is slow. Maybe it depends on projects,
| programming language, etc
| wsesamemr81 wrote:
| this matches my experience exactly
| justacatbot wrote:
| Rule 2 is the one that keeps biting me. You can spend days micro-
| optimizing functions only to realize the real bottleneck was
| storing data in a map when you needed a sorted list. The
| structure of the data almost always determines the structure of
| the code.
| ummonk wrote:
| That's Rule 5 no?
| antirez wrote:
| In programming, the only rule to follow is that there are no
| rules: only taste and design efforts. There are too many
| different conditions and tradeoffs: sometimes what is going to be
| the bottleneck is actually very clear and one could decide to
| design with that already in mind, for instance.
| GuB-42 wrote:
| The opposite conclusion can be taken from the premise of rule #1
| "You can't tell where a program is going to spend its time"
|
| If you can't tell in advance what is performance critical, then
| consider everything to be performance critical.
|
| I would then go against rule #3 "Fancy algorithms are slow when n
| is small, and n is usually small". n is usually small, except
| when it isn't, and as per rule #1, you may not know that ahead of
| time. Assuming n is going to be small is how you get accidentally
| quadratic behavior, such as the infamous GTA bug. So, assume n is
| going to be big unless you are sure it won't be. Understand that
| your users may use your software in ways you don't expect.
|
| Note that if you really want high performance, you should
| properly characterize your "n" so that you can use the
| appropriate technique, it is hard because you need to know all
| your use cases and their implications in advance. Assuming n will
| be big is the easy way!
|
| About rule #4, fancy algorithms are often not harder to
| implement, most of the times, it means using the right library.
|
| About rule #2 (measure), yes, you absolutely should, but it
| doesn't mean you shouldn't consider performance before you
| measure. It would be like saying that you shouldn't worry about
| introducing bugs before testing. You should do your best to make
| your code fast and correct before you start measuring and
| testing.
|
| What I agree with is that you shouldn't introduce speed hacks
| unless you know what you are doing. Most of performance come from
| giving it consideration on every step. Avoiding a copy here,
| using a hash map instead of a linear search there, etc... If you
| have to resort to a hack, it may be because you didn't consider
| performance early enough. For example, if took care of making a
| function fast enough, you may not have to cache results later on.
|
| As for #5, I agree completely. Data is the most important. It
| applies to performance too, especially on modern hardware. To
| give you an very simplified idea, RAM access is about 100x slower
| than running a CPU instruction, it means you can get massive
| speed improvement by making your memory footprint smaller and
| using cache-friendly data structures.
| epolanski wrote:
| > If you can't tell in advance what is performance critical,
| then consider everything to be performance critical.
|
| As for rule 2: first you measure.
| fl0ki wrote:
| > Fancy algorithms are slow when n is small, and n is usually
| small. Fancy algorithms have big constants.
|
| I get where he's coming from, but I've seen people get this very
| wrong in practice. They use an algorithm that's indeed faster for
| small n, which doesn't matter because anything was going to be
| fast enough for small n, meanwhile their algorithm is so slow for
| large n that it ends up becoming a production crisis just a year
| later. They prematurely optimized after all, but for an n that
| did not need optimization, while prematurely pessimizing for an n
| that ultimately did need optimization.
| R0m41nJosh wrote:
| When I was young I took time to "optimize" my code where it
| obviously had no impact, like on simple python scripts. It was
| just by ego, to look smart. I guess the "early optimization"
| takes are aimed at young developers who want to show their skills
| on completely irrelecant places.
|
| Of course with experience, you start to feel when the straight
| forward suboptimal code will cause massive performance issued. In
| this case it's critical to take action up front to avoid the
| mess. Its called software architecture, I guess.
| shashank-100 wrote:
| rules are there until you break them
| vishnugupta wrote:
| I can't emphasize the importance of rule-5 enough.
|
| I learnt about rule-5 through experience before I had heard it
| was a rule.
|
| I used to do tech due diligence for acquisition of companies. I
| had a very short time, about a day. I hit upon a great time saver
| idea of asking them to show their DB schema and explain it. It
| turned out to be surprisingly effective. Once I understood the
| scheme most of the architecture explained itself.
|
| Now I apply the same principle while designing a system.
| SoftTalker wrote:
| Yes, fully agree. Rule 5 has been the center of my approach to
| designing and writing software for over 30 years now. Fad
| methodologies and platforms come and go but Rule 5 works as
| well for me today as it did in 1995.
| artyom wrote:
| I can't agree more. I live and breath by rule #5.
|
| _Getting competent_ at it, however, is no joke and takes
| time.
| nlawalker wrote:
| This reminds me of a portion of a talk Jonathan Blow gave[1],
| where he justifies this from a productivity angle. He explains
| how his initial implementation for virtually everything in Braid
| used arrays of records, and only after finding bottlenecks did he
| make changes, because if he had approached every technical
| challenge by trying to find the optimal data structure and
| algorithm he would never have shipped.
|
| "There's a third thing [beyond speed and memory] that you might
| want to optimize for which is much more important than either of
| these, which is years of your life required per program
| implementation." This is of course from the perspective of a solo
| indie game developer, but it's a good and interesting perspective
| to consider.
|
| [1] https://www.youtube.com/watch?v=JjDsP5n2kSM
| Insanity wrote:
| It's easy to see this outside of the perspective of a solo game
| developer. We all have deadlines to manage even in the regular
| 'corporate world'. And engineering time spent on a problem also
| translates to an actual cost.
|
| It's a good consideration tbh.
| dgb23 wrote:
| It's also notable that video games are programs that run for
| hours and iterate over large sets of very similar entities at
| 60 frames or more per second repeatedly and often do very
| similar operations on each of the entities.
|
| That also means that "just do an array of flat records" is a
| very sane default even if it seems brutish at first.
| quietbritishjim wrote:
| I think when he said "just do an array of flat records" he
| meant as opposed to record of arrays (i.e. row oriented vs
| column oriented), as opposed to fancy data structures which I
| think you're assuming he was implying. Separate arrays for
| each data member are common in game engines exactly because
| they're good for iterating over, which as you said is common.
| O3marchnative wrote:
| That's also great for letting the compiler unlock auto-
| vectorization opportunities without delving into the world
| of manual SIMD.
|
| Even storing something simple such as an array of complex
| numbers as a structure of arrays (SoA) rather than an array
| of structures (AoS) can unlock a lot of optimizations. For
| example, less permutes/shuffles and more arithmetic
| instructions.
|
| Depending on how many fields you actually need when you
| iterate over the data, you prevent cache pollution as well.
| mabster wrote:
| I haven't watched his videos on his language for ages, but
| this was a big thing he wanted in his language: being able
| to swap between array-of-structs and struct-of-array
| quickly and easily.
| MaxBarraclough wrote:
| Jonathan Blow's own unreleased _Jai_ programming language
| has a feature to make it trivial to switch between array-
| of-structs and struct-of-arrays.
|
| From a quick search, it seems HackerNews's own _jcelerier_
| has put together a C++ library for doing this.
| https://github.com/celtera/ahsohtoa
| skeeter2020 wrote:
| I'd be careful extending learnings from games (solo or team
| efforts) to general programming as the needs and intent seem to
| be so different. We rarely see much code re-use in games
| outside of core, special-purpose buy largely isolated
| components and assets. Outside of games there's a much bigger
| emphasis on the data IME, and performance is often a nice-to-
| have.
| awesome_dude wrote:
| Yeah - A game is (generally) a one and done enterprise. Like
| a start up it's all about getting it out the door, there's
| little to no expectation of having to maintain it for any
| real length of time.
| fidotron wrote:
| HN has some hot takes but that one is particularly
| impressive.
|
| Fortnite, Roblox, League of Legends, Counter Strike . . .
| all very short term projects.
| wat10000 wrote:
| For every game like that, there are a thousand games that
| shipped, maybe got a few updates, and then they were
| done.
| awesome_dude wrote:
| We can probably add to that the fact that the nominated
| titles almost certainly started out with spaghetti code
| that had to be refactored, reworked, and gave maintainers
| nightmares in their sleep
| mabster wrote:
| It's been mixed moving to normal code: I haven't had to low-
| level optimise for ages now (man I miss that). But
| performance in the O() sense has been the same.
|
| Game engine development is very much about processing of
| data. The pipeline is long and the tree is wide. Being able
| to reason about complicated data processing topologies mapped
| very easily across.
| suzzer99 wrote:
| > how his initial implementation for virtually everything in
| Braid used arrays of records
|
| This is me with hash maps.
| Fraterkes wrote:
| This is slightly surprising to me, since Braid is kinda
| infamous for being in development for a pretty long time for a
| puzzle platformer
| SatvikBeri wrote:
| Was 3 years a long time for an indie platformer in the early
| 2000s? Looking at some similar examples:
|
| * Braid was 3 years
|
| * Cave Story was 5 years
|
| * World of Goo was 2 years
|
| * Limbo was about 3 years (but with 8-16 people)
|
| So Braid seems pretty average.
| Fraterkes wrote:
| Yeah, you're right. I must've misremembered.
| IshKebab wrote:
| I feel like a game is a bit different though because you
| control the input. You can't profile input you've never seen.
| gowld wrote:
| Jonathan blow has spent the past 10 years and almost all of his
| money trying to build the perfect programming language for his
| 3rd game.
|
| Also, Rule 5 contradicts the idea you quoted from Blow.
| parasense wrote:
| The funny thing is even data structure is really an array of
| memory depending how low down deep one looks. All the people
| who took an intro computer science course knows, those who had
| to implement a heap allocator, it's all really just arrays
| underneath...
| cestith wrote:
| Any software developer who hasn't read _The Practice of
| Programming_ by Kernighan and Pike should. It's not that long and
| much of it is timeless.
| Insanity wrote:
| Yeah, but I doubt many of the newer generation are going to
| read this. I manage a team of engineers, and one of the recent-
| ish graduates asked me in our 1-on-1 if it's still worth
| learning Python given that he can just write prompts. (Python
| is the language all our tools use).
|
| If the next generation doesn't even want to learn a programming
| language, they're definitely not going to learn how to write
| _clean_ code.
|
| Maybe I'm just overly pessimistic about junior engineers at the
| moment because of that conversation lol.
| calepayson wrote:
| Junior here. There are still a few of us who value books and
| documentation. It's a weird time though. Hard to feel
| confident that you're learning in the correct way.
|
| Anyway, I've found that if you want to get a coworker into
| reading technical books, the best way is with a novel or
| three. I've had good success with The Martian. The Phoenix
| Project might work too. Slip them fun books until they've
| built a habit and then drop The Mythical Man Month on them.
| :)
| LVB wrote:
| Here's my optimistic take: the fundamental things that spark
| joy about learning a novel algorithm, pattern, technique,
| etc. haven't gone anywhere, and there's no reason to think
| those things won't continue to be interesting. Furthermore,
| it seems like _reading_ code isn 't going anywhere too soon,
| and that definitely benefits from clean code. It follows that
| someone who can actually recognize clean from spaghetti, and
| tell the LLM to refactor it into XYZ style, is going to be
| relatively more valuable.
|
| Random side note: my teen son has grown up with iPhone-level
| tech, yet likes and finds my old Casio F91 watch very
| interesting. I still have faith :)
| wduquette wrote:
| In almost forty years of experience, the fraction of
| developers I've known who read in the field beyond what's
| strictly needed for their task is _very_ small. I 'm always
| delighted when I find one.
| fwip wrote:
| I obviously wasn't there, but it sounds like maybe they were
| asking for reassurance. There's a lot of people out there
| saying that LLMs are going to totally replace regular
| programming, and for a new grad who doesn't know much about
| the world, they value your expertise.
| Insanity wrote:
| That's a positive interpretation. You might be right,
| either way that's what I pointed them to. I don't think the
| LLMs will really replace engineers in the foreseeable
| future, and so learning the languages and the fundamentals
| is still needed.
| cestith wrote:
| I have a laptop and a phone right here, right now. I have
| actual calculators around here somewhere. I've been out
| of schools for decades. I still can do arithmetic and
| basic algebra in my head or on paper and often do.
|
| I'm hoping the situation with LLMs will be the same.
| Teach the basics and allow people to fall back on them
| for at least the simpler tasks for their lifetimes. I
| know people, by the way, who can still use an abacus and
| a slide rule. I can too, but with a refresher beforehand
| because I seldom use those.
| kshacker wrote:
| IMO it is a valid question. Our AI has not yet reached that
| level, our prompts have not yet reached that level of
| sophistication. But I do not code in assembly any more, I do
| not do pointer arithmetic any more, so maybe some day we get
| to a state where we do not write python also. It is not going
| to be soon despite the AI bandwagon saying so, there are too
| many legacy pieces that are not documented well and not easy
| decipherable due to context window limits. But in 10 years
| ...maybe prompts is all we need.
|
| PS: Not that we do not have people working at all levels of
| stack today, just that each level of stack, like a discussion
| going on today about python's JIT compiler will be a few
| (dozen or hundred) specialists. Everyone else can work with
| prompts.
| ryguz wrote:
| The interesting thing about Rule 1 is that it makes Rules 3-5
| follow almost mechanically. If you genuinely accept that you
| cannot predict where the bottleneck is, then writing
| straightforward code and measuring becomes the only rational
| strategy. The problem is most people treat these rules as
| independent guidelines rather than as consequences of a single
| premise.
|
| In practice what I see fail most often is not premature
| optimization but premature abstraction. People build elaborate
| indirection layers for flexibility they never need, and those
| layers impose real costs on every future reader of the code. The
| irony is that abstraction is supposed to manage complexity but
| prematurely applied it just creates a different kind.
| eru wrote:
| > In practice what I see fail most often is not premature
| optimization but premature abstraction.
|
| Compare and contrast https://people.mpi-
| sws.org/~dreyer/tor/papers/wadler.pdf
| tasuki wrote:
| Philip Wadler gave us a sound type system. Rob Pike gave us a
| programming language for stupid people. Each contributed in
| their own way, towards different goals.
| rob wrote:
| Really need that [flag bot] button added to HN.
| tech_hutch wrote:
| Are you saying the parent comment seems like a bot?
| macintux wrote:
| Comment history is suspect.
| rd wrote:
| It would be easier if we could just block comments from green
| users. I get that it loses ~.1% of authors who might have
| made an account to comment on a blogpost of theirs that was
| posted here. I'd rather have that loss than have to deal with
| the 99.9% of spam.
| suzzer99 wrote:
| TIL green means new. I thought it was special for some
| reason.
| tracker1 wrote:
| You tend to see it a lot in "Enterprise" software (.Net and
| Java shops in particular). A lot of Enterprise Software
| Architects will reach for their favored abstractions out of
| practice as opposed to if they fit. Custom solution providers
| will build a bunch of the same out of practice.
|
| This is something I tend to consider far, far worse than "AI
| Slop" in practice. I always hated Microsoft Enterprise
| Library's Data Access Application Block (DAAB) in practice.
| I've literally only ever seen one product that supported
| multiple database backends that necessitated that level of
| abstraction... but I've seen that library well over a dozen
| times in practice. Just as a specific example.
|
| IMO, abstractions should generally serve to make the rest of
| the codebase reasonable more often than not... abstractions
| that hide complexity are useful... abstractions that add
| complexity much less so.
| silisili wrote:
| > In practice what I see fail most often is not premature
| optimization but premature abstraction
|
| This matches my experience as well.
|
| Someone here commented once that abstractions should be
| emergent, not speculative, and I loved that line so much I use
| it with my team all the time now when I see the craziness
| starting.
| hugey010 wrote:
| I completely agree with you, and that is an amazing quote.
| senderista wrote:
| "Abstractions should be written in blood"
| fl0ki wrote:
| I only agree if you have a bounded dataset size that you know
| will never grow. If it can grow in future (and if you're not
| sure, you should assume it can), not only will many data
| structures and algorithms scale poorly along the way, but they
| will grow to dominate the bottleneck as well. By the time it no
| longer meets requirements and you get a trouble ticket, you're
| now under time pressure to develop, qualify, and deploy a new
| solution. You're much more likely to encounter regressions when
| doing this under time pressure.
|
| If you've been monitoring properly, you buy yourself time
| before it becomes a problem as such, but in my experience most
| developers who don't anticipate load scaling also don't monitor
| properly.
|
| I've seen a "senior software engineer with 20 years of industry
| experience" put code into production that ended up needing 30
| minute timeouts for a HTTP response only 2 years after initial
| deployment. That is not a typo, 30 minutes. I had to take over
| and rewrite their "simple" code to stop the VP-level
| escalations our org received because of this engineering
| philosophy.
| 9rx wrote:
| _> You 're much more likely to encounter regressions when
| doing this under time pressure._
|
| There is nothing to suggest you should wait to optimize under
| pressure, only that you should optimize only after you have
| measured. Benchmark tests are still best written during the
| development cycle, not while running hot in production.
|
| Starting with the naive solution helps quickly ensure that
| your API is sensible and that your testing/benchmarking is in
| good shape before you start poking at the hard bits where you
| are much more likely to screw things up, all while offering a
| baseline score to prove that your optimizations are actually
| necessary and an improvement.
| munk-a wrote:
| As someone who believes strongly in type based programming and
| the importance of good data structure choice I'm not seeing how
| Rule 5 follows Rule 1. I think it's important to reinforce how
| impactful good data structure choice is compared to trying to
| solve everything through procedural logic since a well
| structured coordination of data interactions can end up greatly
| simplifying the amount of standalone logic.
| astrobe_ wrote:
| Data cache issues is one case of something being surprising
| slow because of how data is organized. That said, Structure
| of Arrays vs Array of structures is an example where rule 4
| and 5 somewhat contradict each other, if one confuses
| "simple" and "easy" - Structure of Array style is "harder"
| because we don't see it often; but then if it's harder, it is
| is likely more bug-prone.
| akkad33 wrote:
| But good data structure is not always evident from the get
| go. And if your types are too specific it would make future
| development hard if the specs change. This is what I struggle
| with
| munk-a wrote:
| Professionally I'm a data architect. Modeling data in a way
| that is functional, performant and forward facing is not an
| easy problem so it's perfectly fine to struggle with it. We
| do our best job with what we've got within reasonable
| constraints - we can't do anything more than that.
|
| I found that over time my senses have been honed to more
| quickly identify things that are important to deeply study
| and plan right now and areas where I can skimp more and fix
| it later if problems develop. I don't know if there was a
| short cut to honing those senses that didn't involve a lot
| of pain as I needed to pick apart and rework oversights.
| mkehrt wrote:
| This comment is fascinating to me, as it indicates an entirely
| different mindset than mine. I'm much more interested in code
| readability and maintainabilty (and simplicty and elegance)
| than performance, unless it's necessary. So I would start by
| saying everything flows from rule 4 or maybe 5. Rule 1 is a
| consequence of rule 4 for me.
| Eiriksmal wrote:
| Maybe it's because the comment you are replying to is from a
| new account posting paragraphs of LLMese in multiple comments
| in the same minute. It's unsurprising that soulless LLM
| output doesn't match your mindset!
| gowld wrote:
| That account has posted 3 comments in 3 hours.
|
| https://news.ycombinator.com/threads?id=ryguz
| pc86 wrote:
| I was just dealing with this is some home-grown configuration
| nightmare where every line of the file was pulled from some
| other namespace to the point where you end up with two dozen
| folders, each with half a dozen partial configuration files in
| them, and it takes half a hour to figure out where a single
| value is coming from.
|
| I'm sure it's super flexible but the exactly same thing could
| have been achieved with 8 YAML files and 60% of the content
| between them would be identical.
| hugey010 wrote:
| Premature abstraction is one of the worst pitfalls when writing
| software. It's paid for up front, it costs developer time to
| understand and work with, it adds complexity (tech debt),
| increases likeliness of bugs, and increases refactor time. All
| for someone to say "if we ever want to do X". If we wanted to
| do it, we'd do it now.
|
| I truly believe this comes from devs who want to feel smart by
| "architecting" solutions to future problems before those
| problems have become well defined.
| tracker1 wrote:
| Pretty much live by these in practice... I've had a lot of
| arguments over #3 though... yes nested loops can cause
| problems... but when you're dealing with < 100 or so items in
| each nested loop and outer loop, it's not a big deal in practice.
| It's simpler and easier to reason with... don't optimize unless
| you really need to for practical reasons.
|
| On #5, I think most people tend to just lean on RDBMS databases
| for a lot of data access patterns. I think it helps to have some
| fundamental understandings in terms of where/how/why you can
| optimize databases as well as where it make sense to consider
| non-relational (no-sql) databases too. A poorly structured
| database can crawl under a relatively small number of users.
| jkaptur wrote:
| It's interesting to contrast "Measure. Don't tune for speed until
| you've measured" with Jeff Dean's "Latency Numbers Every
| Programmer Should Know" [0].
|
| Dean is saying (implicitly) that you _can_ estimate performance,
| and therefore you can design for speed a priori - without
| measuring, and, indeed, before there is anything to measure.
|
| I suspect that both authors would agree that there's a happy
| medium: you absolutely can and should use your knowledge to
| design for speed, but given an implementation of a reasonable
| design, you need measurement to "tune" or improve incrementally.
|
| 0: https://gist.github.com/jboner/2841832
| eschneider wrote:
| I mean...you should always design with speed in mind (In that
| Jeff Dean sense :) but what 'premature optimization' is
| referring to, is more like localized speed optimizations/hacks.
| Don't do those until a) you know you'll need it and b) you know
| where it will help.
| sifar wrote:
| Yeah, the latency numbers provide a ceiling for your algorithm.
| The actual performance depends on the implementation, code
| generation, runtime hazards, small dependencies one may have
| overlooked etc.
| SatvikBeri wrote:
| I've had the pleasure of working with some truly fast pieces of
| code written by experts. It's always both. You have to have a
| good sense of what's generally fast and what's not in order to
| design a system that doesn't contain intractable bottlenecks.
| And once you have a good design you can profile and optimize
| the remaining constraints.
|
| But e.g. if you want to do fast math, you really need to design
| your pipeline around cache efficiency from the beginning - it's
| very hard to retrofit. Whereas reducing memory allocations in
| order to make parallel algorithms faster is something you can
| usually do after profiling.
| PaulHoule wrote:
| The "bottleneck" model of performance has limitations.
|
| There are a lot of systems where useless work and other
| inefficiencies are spread all over the place. Even though I think
| garbage collection is underrated (e.g. Rustifarians will agree
| with me in 15 years) it's a good example because of the
| nonlocality that profilers miss or misunderstand.
|
| You can make great prop bets around "I'll rewrite your Array-of-
| Structures code to Structure-of-Arrays code and it will get much
| faster"
|
| https://en.wikipedia.org/wiki/AoS_and_SoA
|
| because SoA usually is much more cache friendly and AoS makes the
| memory hierarchy perform poorly in a way profilers can't see. The
| more time somebody spends looking at profilers and more they
| quote Rule 1 the more they get blindsided by it.
| okamiueru wrote:
| Rule 1 seems similar to Donald Knuths "premature optimization"
| from 1974.
|
| > Programmers waste enormous amounts of time thinking about, or
| worrying about, the speed of noncritical parts of their programs,
| and these attempts at efficiency actually have a strong negative
| impact when debugging and maintenance are considered. We should
| forget about small efficiencies, say about 97% of the time:
| premature optimization is the root of all evil. Yet we should not
| pass up our opportunities in that critical 3%.
|
| Rule 2 follows rule 1.
|
| Rule 3 & 4 is a variation of Keep it Simple, Stupid (KISS) from
| the 1960s.
|
| ... and... now I feel stupid, because I read the last part, which
| is summarizing it in the same way.
| dreko wrote:
| Later never comes" is true, but the fix isn't to optimize early,
| it's to write code simple enough that optimization is easy when
| later finally does come. That's what Rule 5 is really about. Get
| the data structures right and the rest is tractable.
| munro wrote:
| > Rule 5. Data dominates. If you've chosen the right data
| structures and organized things well, the algorithms will almost
| always be self-evident. Data structures, not algorithms, are
| central to programming.
|
| It's so true, when specing things I always try to focused on DDL
| because even the UI will fall into place as well, and a place I
| see claude opus fail as well when building things.
| cleaver wrote:
| I recall a similar statement from Ed Yourdon in one of his
| books (90's?)
| EvanAnderson wrote:
| The article makes reference to Fred Brooks and "The Mythical
| Man Month", but doesn't make a direct quote. The quote I'd
| have referenced is:
|
| "Show me your flowchart and conceal your tables, and I shall
| continue to be mystified. Show me your tables, and I won't
| usually need your flowchart; it'll be obvious." -- Fred
| Brooks, The Mythical Man Month (1975)
| oxag3n wrote:
| > Rule 5. Data dominates. If you've chosen the right data
| structures and organized things well, the algorithms will almost
| always be self-evident. Data structures, not algorithms, are
| central to programming.
|
| I'm a big fan of Data Oriented Design. Once you conceptualize how
| data is stored and transformed in your program, it just has to be
| reflected in data structures that make it possible.
|
| Modern design approaches tend to focus on choosing a right
| abstraction like columnar/row layout, caching etc. They mostly
| fail to optimally work with the data. Optimal in this case
| meaning getting most of all underlying hardware capabilities, for
| example reading large and preferably continuous blocks of data
| from magnetic storage, parallel data processing, keeping
| intermediate results in CPU caches, utilizing all physical SSD
| queues.
| aaronblohowiak wrote:
| The fundamental tension between nouns and verbs and the
| attempts to unify them like events have made programming a long
| art form to study.
|
| It's all use-case and priority-specific, and I think the more
| varied your experience and more tools you have in the tool
| belt, the better off you can be to bring the right solution to
| bear. Of course, then you think you have the right solution in
| mind (lets say using partitions in postgres for something) but
| you find the ORM your service is using doesn't support it, then
| what is "best" becomes not only problem-specific but also tool-
| specific. Finally, even if you have the best solution and your
| existing ecosystem supports it but the rest of the engineering
| staff you have is unfamiliar with it, it may again no longer be
| "best".
|
| this ladder of problem-fit, ecosystem-fit, staffing-fit is
| something I have grappled with in my career.
|
| LLMs are only so-so at any of the above (even when including
| the agent as "staff".)
| ryguz wrote:
| Rule 5 about data dominating resonates most in modern systems.
| The trend of just throwing more code at it when most performance
| and correctness issues come down to how data flows through the
| system. Most junior engineers optimize the wrong layer because
| they start with the code instead of the data model.
| makeitrain wrote:
| Here's the modern version: https://grugbrain.dev/
| sunnyos wrote:
| Seem logical
| awesome_dude wrote:
| I received some 'interesting' feedback when I spoke about
| commenting that I was using an O(n) search instead of an O(log n)
| algorithm because of the normally small size of n [0]
|
| What I should have done was point to Rob's third rule (either in
| my comment or in the resulting threads)
|
| [0]
| https://news.ycombinator.com/threads?id=awesome_dude&next=47...
| IvyMike wrote:
| Once upon a time in the 90's I was at work at 2am and I needed to
| implement a search over a data set. This function was going to be
| eventually called for every item, thus if I implemented it as a
| linear search, it would be n^2 behavior. Since it was so late and
| I was so tired, I marked it as something to fix later, and just
| did linear search.
|
| Later that week, now that things were working, I profiled the n^2
| search. The software controlled a piece of industrial test
| equipment, and the actual test process would take something
| around 4 hours to complete. Using the very worst case, far-
| beyond-reasonable data set, if I left the n^2 behavior in, would
| have added something like 6 seconds to that 4 hour runtime.
|
| (Ultimately I fixed it anyways, but because it was easy, not
| because it mattered.)
| senderista wrote:
| For small enough n, linear search might have been faster.
| bsder wrote:
| The problem with O(n^2) algorithms is that they are fast enough
| to get into production and slow enough to explode in
| production.
| jancsika wrote:
| Can you actually follow rule #1 for things like realtime audio
| programming?
| eichin wrote:
| Heh, in the early days of C++ (1990ish) I had a notable
| application of 3+4 involving a doubly linked list with cache
| pointers (time-sequence data browser so references were likely
| "nearby" as the user zoomed in; spec was to handle streaming data
| eventually.) Had problems with it crashing in pointer-related
| ways (in 1990, _nobody_ had a lot of C++ experience) so I cooked
| up a really dumb "just realloc an array" version so I could
| figure out if the problem was above or below data structure...
| and not only didn't the "dumb" version crash, it was also much
| faster (and of faster order!) due to amortized realloc - doing a
| more expensive operation much less often turns out to be a really
| good trick :-)
| rsc wrote:
| Worth noting these were not written as rules of programming
| generally but rules specifically targeted at complexity. They are
| lifted from the "Complexity" section of Rob's "Notes on
| Programming in C".
|
| https://www.lysator.liu.se/c/pikestyle.html
| http://www.literateprogramming.com/pikestyle.pdf
| up2isomorphism wrote:
| Even agree with most of the stuff he said, however in real life,
| you won't be able to win a fight using these arguments. You can
| only create a environment to execute these strategies first to
| get a good product and them use them as a propaganda afterwards.
| nelsonfigueroa wrote:
| > Data structures, not algorithms, are central to programming
|
| I'm a big time leetcode interview hater and reading that felt
| validating. Why the f*ck am I always asked about algorithms.
___________________________________________________________________
(page generated 2026-03-18 23:00 UTC)