33 ms·
Rob Pike's Rules of Programming (1989)
- cactus2093 6y agoInteresting that the first 3 are all about performance. Which strikes me as a bit ironic given rule #1, which could be summarized as don't worry about performance until you have to.
- jonfw 6y ago"Write stupid code that uses smart objects" That's a good one. It's amazing how much complexity can be created by using the wrong abstractions.
- jaggederest 6y agoI frequently find that, when refactoring especially, you find a lot of big ol' god objects that are incomprehensible. But when you break them down into 5-10 small objects, suddenly the operation they were trying to do makes perfect sense.
- aciswhat 6y agommmm very true with Redux --> context+hook state
- chubot 6y agoFWIW I find this is especially important for compilers and interpreters. It's not an exaggeration to say that such programs are basically big data structures, full of compromises to accomodate the algorithms you need to run on them. For example LLVM IR is just a big data structure. Lattner has been saying for awhile that a major design mistake in Clang is not to have its own IR (in the talks on the new MLIR project). SSA is data structure with some invariants that make a bunch of algorithms easier to write (and I think it improves their computational complexity over naive algorithms in several cases) ---- In Oil I used a DSL to describe an elaborate data structure that describes all of shell: What is Zephyr ASDL? http://www.oilshell.org/blog/2016/12/11.html http://www.oilshell.org/blog/2016/12/11.html https://www.oilshell.org/release/0.8.pre9/source-code.wwz/frontend/syntax.asdl https://www.oilshell.org/release/0.8.pre9/source-code.wwz/fr... I added some nice properties that algebraic data types in some language don't have, e.g. variants are "first class" unlike in Rust. Related: I noticed recently that Rust IDE support has a related DSL for its data structure representation: https://internals.rust-lang.org/t/announcement-simple-production-ready-rust-un-grammar/12827 https://internals.rust-lang.org/t/announcement-simple-produc...
- mamcx 6y ago> FWIW I find this is especially important for compilers and interpreters. Totally. I'm building a relational language and start to get very obvious why RDBMS not fit certain purity ideals of the relational model (like all relations are sets, not bags). I'm stuck in deciding which structures provide by default. Dancing between flat vectors or ndarrays or split between flat vectors (columns), and HashMaps/BTree with n-values (this is my intuition now). --- > I added some nice properties that algebraic data types in some language don't have, e.g. variants are "first class" unlike in Rust. This sound cool, where I can learn about this?
- chubot 6y agoFWIW I found this post thought provoking in thinking about data models of languages. https://news.ycombinator.com/item?id=13293290 https://news.ycombinator.com/item?id=13293290 --- About first class variants: https://lobste.rs/s/77nu3d/oil_s_parser_is_160x_200x_faster_than_it_was#c_gu4oaj https://lobste.rs/s/77nu3d/oil_s_parser_is_160x_200x_faster_... https://github.com/rust-lang/rfcs/pull/2593 https://github.com/rust-lang/rfcs/pull/2593 Another way I think of this is "types vs. tags": https://oilshell.zulipchat.com/#narrow/stream/208950-zephyr-asdl/topic/Better.20solution.3A.20tags.20vs.2E.20types https://oilshell.zulipchat.com/#narrow/stream/208950-zephyr-... (Zulip, requires login) Basically variant can types stand alone, and have a unique tag. Tags are discriminated at RUNTIME with "pattern matching". But a variant can belong to multiple sum types, and that's checked statically. This is modeled with multiple inheritance in OOP, but there's no implementation inheritance. Related: https://pling.jondgoodwin.com/post/when-sum-types-inherit/ https://pling.jondgoodwin.com/post/when-sum-types-inherit/ So basically in the ASDL and C++ and Python type system I can model: - a Token type is a leaf in an arithmetic expression - a Token type is a leaf in an word expression But it's not a leaf in say what goes in a[i], or dozens of other sum types. Shell is a big composition of sublanguages, so this is very useful and natural. Another construct that appears in multiple places is ${x}. So having these invariants modeled by the type system is very useful, and actually C++ and MyPy are surprisingly more expressive than Rust! (due to multiple inheritance) Search for %Token here, the syntax I made up for including a first class variant into a sum type: https://www.oilshell.org/release/0.8.pre9/source-code.wwz/frontend/syntax.asdl https://www.oilshell.org/release/0.8.pre9/source-code.wwz/fr... There is a name for the type, and a name for the tag (and multiple names for the same integer tag). Tags (dynamic) and types (static) are decoupled.
- chrisweekly 6y agoYes! We should replace DRY (don't repeat yourself) with AHA (avoid hasty abstractions), as the dominant rule of thumb.
- jonfw 6y agoIt's key to write code that can be easily re-factored, because most of the time you come up with a much better idea a week later.
- deleted 6y ago[deleted]
- andrewl 6y agoIn The Mythical Man Month Fred Brooks said "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." I first read that on Guy Steele's site: http://www.dreamsongs.com/ObjectsHaveNotFailedNarr.html http://www.dreamsongs.com/ObjectsHaveNotFailedNarr.html
- rjsw 6y ago>I first read that on Guy Steele's site. It isn't Guy Steele's website. That page was written by him but the website is owned by Richard P Gabriel.
- deleted 6y ago[deleted]
- monocasa 6y agoResaid by Linus with a bit more modern nomeclature (and Linus's trademark bluntness): > Bad programmers worry about the code. Good programmers worry about data structures and their relationships
- mgkimsal 6y ago> Bad programmers worry about the code And yet, I see a whole swath of the industry hyper-focused on various linters/styling/rules.
- karl11 6y agoEveryone building no code tools is learning or will learn that the problem most businesses have is not a lack of coding skill, or the inability to build the algorithm, but rather how to structure and model data in a sensible way in the first place.
- throwaway894345 6y agoModeling the data and structuring the program are indeed the harder tasks, but orgs have lots of smart people who have those skills but not the familiarity with various existing syntaxes and standard libraries and so on that a programmer learns over the decades of their career. Further, those same orgs probably have many people with experience in the latter but without any special ability to think abstractly. This significantly limits the ability to create tools. Further, the no code tools often abstract at a more appropriate level than general purpose programming languages’ standard libraries because these tools aren’t trying to be general purpose (at least not to the same degree as general purpose programming languages). Lastly, I’ve seen business people use certain no code tools to build internal solutions quickly that would have taken a programmer considerable (but not crazy) time to crank out, especially considering things like CI/CD pipelines, etc. Nocode won’t replace Python, but it serves a valuable niche.
- tmaly 6y agoIf no code tools are anything like ORMs, there will be some interesting surprises when one encounters non-normalized data structures.
- bballer 6y agoI've been preaching this to all my non-coder creative marketing type buddies who have ideas all the time and think they can just whip up a product using all the latest and greatest no-code tooling. They are destined for failure.
- terandle 6y agoAm I wrong to avoid writing O(n^2) code if at all possible when it is fairly easy to use hash tables for a better time complexity? Sure when n is small the O(n^2) one will be faster but when n is small /anything/ you do is fast in absolute terms so I'm trying to not leave traps in my code just waiting for n to get bigger than initially expected.
- deleted 6y ago[deleted]
- fabian2k 6y agoI would not read these rules as anything like suggesting to write O(n^2) code. I think at best I'd read them as favoring O(n) instead of (1) for small n, but I really think that "fancy" algorithms in this case doesn't mean obvious optimizations like this. If you can't guarantee n is small, I think it is entirely sensible to use a dictionary/hash table instead of looping over an array or list. As long as n is small the overhead is probably irrelevant, and it'll prevent surprises if n gets large as you said. And if the difference actually matters, you get back to rule 1 and 2 and measure first anyway.
- mav3rick 6y agoUsing array based data structures also get you more cache hits. For smaller data sets, this may well be faster than a fancy algorithm.
- bluGill 6y agoThis is true only if you are iterating over the entire array often. If you only rarely need to access one data member the array will not be in cache and so you have less to load from memory. Depending on how your data is structured the array may or may not save time even in small sizes.
- mav3rick 6y agoOf course temporal and spatial locality are important.
- Ozzie_osman 6y agoIt turns out rule 5 (Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident) is both true but also hard. Eric Evans' Domain Driven Design is a good book on the topic.
- paloaltokid 6y agoNot only is it hard, it's the one thing that if you get it right, your technical foundation will be rock solid. But it's the thing most teams and organizations neglect to spend enough time on. I often wonder why this is the case -- my first mentors taught me that logical data modeling was a really important skill. But I never talk about third normal form or any such things with my peers.
- yashap 6y agoI’m such a huge fan of DDD. IMO, if you only ever read one book on Software Architecture, that’s the one to pick. A key point, though, is that you learn the right domain models/abstractions over time. Refactoring is critical as you gain more insight into the domain. If you’re constantly questioning your modelling of the domain, and refactoring towards a better one, you’ll end up with a great model and thus a clean, understandable, easy to extend/modify system. If you stick with whatever abstractions you chose at the start, when you knew way less about the domain/business problems, you’ll likely end up with poor abstractions, and a code based that’s slow, tedious and error prone to modify. Convincing the business that it’s worth setting aside time to constantly refactor towards better domain models is often the hardest part, but crucial.
- Supermancho 6y ago> If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident) is both true but also hard. The problem is not the self-evident algorithm, but the delicate implementation (or god forbid, at scale). Take in 1000 web requests per second. The data is all strictly validated and has about 60 fields a record/req plus dealing with errors. How does that go from webserver to (rolls dice) kafka to a (rolls dice) cassandra that can be queried accurately and timely? How much does that cost? Oh, that's not a programmer problem. Except it is. Creating a fantasy niche of describing problems as data vs algorithm is the canonical ivory tower disconnect.
- lliamander 6y agoRule 5 seems to mirror one of my favorite insights from Alexander Stepanov: > In 1976, still back in the USSR, I got a very serious case of food poisoning from eating raw fish. While in the hospital, in the state of delirium, I suddenly realized that the ability to add numbers in parallel depends on the fact that addition is associative. (So, putting it simply, STL is the result of a bacterial infection.) In other words, I realized that a parallel reduction algorithm is associated with a semigroup structure type. That is the fundamental point: algorithms are defined on algebraic structures. This is also exemplified in the analytics infrastructure used at stripe: https://www.infoq.com/presentations/abstract-algebra-analytics/ https://www.infoq.com/presentations/abstract-algebra-analyti...
- sukilot 6y agoAnd that was 10 years before Haskell went huge in that idea.
- lliamander 6y agoI'm not super familiar with either the C++ or Haskell communities, but Stepanov's notion of Generic Programming[1] certainly seems to fit with the Haskell ethos. [1]http://www.generic-programming.org/ http://www.generic-programming.org/
- skybrian 6y agoBut adding floating point numbers isn't associative, in general. Sometimes you need to do it the right way to avoid catastrophic cancellation. I guess the key is to know how to deal with things that are only mostly true.
- lliamander 6y agoThat's true about floating point numbers. I assume that depending upon the context, it may not be a big issue (e.g. GPU compute)? In any case, the point Stepanov was making is that if you want to be able to use a certain algorithm, then you have to make a choice to represent your data in a way that enables that algorithm, and the way you know whether the structure is appropriate for that algorithm is the algebraic properties of the structure.
- mywittyname 6y ago> "write stupid code that uses smart objects". Writing stupid code is actually really difficult. For me, it takes a little bit of iterating before I know just the right place to insert stupid.
- dnautics 6y agoDo you use TDD? I'm not religious about it in general, but when I'm lost, confused, and easily distracted, I start with TDD to write the dumbest possible code.
- sukilot 6y agoTDD is good for features (like web apps) but not so much for algorithms. The difference is that you only need to support a tiny fraction of possible features / use cases, but your algorithms need to be correct for a wide range of inputs.
- dnautics 6y agoI disagree. You code your algo for one input, come up with a corner case, write a failing test, refactor, repeat. For an algo, let's say it operates on a list, I'll start with test f([]) == 0, and implement f to output the constant 0. And then go from there.
- bluGill 6y agoThat only works if the algorithm isn't already understood and so you don't know what optimal is. If you tdd sort there is no way to get divide the list to small chunks, insert sort each small chunk, then merge sort them. (20 years ago this is what gnu sort did, I assume that this algorithm has changed now that cache is a bigger factor in performance). Even knowing that the above is your end goal TDD to get there is wrong because you don't know how the best algorithm will change when something else comes up as important. Tests are good, but they need to be universal for any implementation, which means you often cannot tests the internal details that prove you didn't use bogo sort (picking a pathological example to make the point)
- sethammons 6y agoA quote from one of our founders that I've always liked: If you make an optimization that was not at a bottleneck, you did not make an optimization.
- NewEntryHN 6y agoYou made an optimization for the future when enough bottlenecks have been fixed such that this one part becomes the bottleneck.
- chubot 6y agoExcept that there are infinite such non-bottlenecks, and all the effort you spend on there is effort not spent on the real bottlenecks. In other words, all engineering is time- and cost-constrained. Anybody can build a good chair for $10,000 or a good PC for $100,000. Doesn't mean it's good engineering.
- nix23 6y ago>not spent on the real bottlenecks BE LOGICAL! Of course you first fix the big bottlenecks. >good PC for $100,000. Doesn't mean it's good engineering. Of course it is...or can you gold platter a pc case?
- jorangreef 6y ago"Anybody can build a good chair for $10,000 or a good PC for $100,000." And some people can build a great PC for $1,000 that runs circles around the good PC for $100,000. There's so much more to engineering than thinking in terms of time and cost constraints. Those are real constraints, but they're not the most important. Engineering is design. If you have good design, good insight, you can do things that people with infinite time and budget could never dream to achieve. You can start making a product that's a hundred times more powerful for a tenth of the price in a fraction of the time. If you don't have good design, good insight, then no amount of time or budget can help you.
- Koshkin 6y ago
- jorangreef 6y agoRule 1 and 2 depend on context, whether you're working on an existing program or a new program. They can be true or false. They can really help or they can really hurt. Are you going into an existing system to do performance optimization? Sure, don't guess, measure. Are you designing a new system? Throw out those parroted premature optimization mantras... you are responsible for designing for performance upfront. You will always measure but depending on context you will design for speed first and then test your prototype with measurements. There's no way around an initial hypothesis when you're designing new systems. You have to start somewhere. That's where Jeff Dean's rule always to do back of the envelope guesses will pay off in orders of magnitude, many times over. Rule 3 and 4 are gold and always true. Rule 5 is the key to good design.
- svec 6y agoPike himself says "there's a 6th rule": https://twitter.com/rob_pike/status/998681790037442561?lang=en https://twitter.com/rob_pike/status/998681790037442561?lang=... (6. There is no Rule 6.) And points to the best source he finds for it on the web: http://doc.cat-v.org/bell_labs/pikestyle http://doc.cat-v.org/bell_labs/pikestyle
- tinco 6y agodang if this sticks to the frontpage, can you change the title to "Rob Pike's 5 rules of programming in C"? As the title is now it misrepresents Rob Pikes words.
- commandlinefan 6y ago> Tony Hoare's famous maxim "Premature optimization is the root of all evil." Actually that was Donald Knuth - it's an urban legend that it's an urban legend that it was originally Knuth. Hoare was quoting Knuth, but Knuth forgot he said it, and re-mis-attributed the quote to Hoare.
- RoutinePlayer 6y agoThis reminds me of that Woody Allen joke about someone translating all the T.S. Eliot’s poems into English after some vandals had broken into the school library and translated them into French.
- karmakaze 6y agoAnd it is usually quoted out of its context. "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%."
- hombre_fatal 6y agoI don't think that changes the meaning. Once that 3% matters to you and you've invested the work to measure that 3%, it's not premature anymore. That "premature" and "optimization" are undefined and left up for debate is what makes it trite.
- YZF 6y agoIt does change the meaning IMO. It means than 3% of the time you should be doing "premature" optimization. The point of most people referring to this quote is never try to optimize anything as you write it. First build your system(?), then measure it, then optimize it. Knuth's point is that this attitude is ok most of the time, but sometimes it's not ok. Another way of putting this is that most of the code, for most applications, isn't performance critical. But some code is. Sure, you can't always tell in advance, but sometimes you can. This is sort of the difference between terrible software that will always suck and well crafted software, no amount of measurement or after-the-fact optimization will turn that terrible software into well crafted software. The other aspect that I think is often missed is that these observations are often made at different scales. You can look at relatively short algorithm (let's say merge sort) and it may not be obvious which instructions are the ones that need to be optimized and what the bottlenecks will be, execution units, data access e.g. So you start with a reasonable but maybe naive implementation and then you optimize from there. That's a pretty solid idea. But taking that idea to a higher scale level, e.g. saying we're going to build this huge system with a billion lines of code and so we'll just throw something together and measure it isn't exactly the same thing, that's a pretty problematic idea. You need to be able to anticipate what the bottlenecks in your billion line system are going to be because finding that out after you've written a billion lines could be a big deal. [EDIT: and really this whole long story is why these sort of rules don't work. Because the people who know (have the experience/craftsmanship) don't need the rule and the people who don't know won't understand it. It's like reading a book about sword fighting and then trying to go into a sword fight... The reading can complement your training but can't be substitute...]
- sam_lowry_ 6y ago"Bad programmers worry about the code. Good programmers worry about data structures and their relationships." — Linus Torvalds
- eointierney 6y agoAmateur mathematicians worry about patterns, professionals worry about numbers
- codemonkey-zeta 6y agoI'm neither an amateur nor professional mathematician, so I can't tell; is this statement tongue-in-cheek? If not, what does it actually mean?
- ChrisMarshallNY 6y agoI've always taken a very practical, results-oriented approach to software development. That makes sense, to me. One of the first things that we learned, when optimizing our code, was to use a profiler. Bottlenecks could be in very strange places, like breaking L2 caches. That would happen when data was just a bit too big, or a method was called; forcing a stack frame update. We wouldn't see this kind of thing until we looked at a profiler; sometimes, a rather advanced one, provided by Intel.
- nurettin 6y agoThese rules look silly when you know that your tight loop that waits for IO or redundantly computes things needs caching. No, you don't need to measure that, and you know that your tight loop function is going to be the bottleneck. Everyone knows that. Now it does make sense when you introduce an entire constraint library instead of looping over 3-4 variables with a small search space. But again, you know it is a small search space. You know you don't have to optimize it. I really don't get these rules. Edit: Go ahead and roast me, but keep in mind I've probably been there and back.
- zimpenfish 6y ago> No, you don't need to measure that Just this evening I came across some code which pasted an image on top of a blue background (in Go) that set every individual pixel to the background, then got every pixel from the source and set the corresponding pixel of the destination to that colour. I figured it'd be quicker to paste the source onto the destination with `image/draw`. Turns out, if you're using NRGBA images, it's 40-50% slower. That's definitely an "obvious optimisation" that was proven wrong by measurement. (If you're using RGBA images, though, the pasting method is 300% faster. Because obviously.)
- game_the0ry 6y ago> 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. :O Epiphany
- Areading314 6y agoThese resonate, especially #1, but I'm not so sure about #5. Although it makes sense to choose good data structures, I don't think that guarantees a simpler algorithm. For example you can store your data in a heap (tree), and still need to write a tree traversal algorithm to print out the elements in order.
- dogbox 6y ago> 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. Is "data structures" the correct term here? Assuming I'm not misinterpreting, the usage of "data structures" can be misleading - one usually thinks of things like BST's and hash tables, which are inherently tied to algorithms. I feel like "data modeling" better captures the intended meaning here.
- deleted 6y ago[deleted]
- hellofunk 6y agoA custom type is also a data structure and that is usually what I think quotes like these refer to.
- rubyn00bie 6y ago> 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. That one hits me in the feels because I think a lot of folks focus on algorithms (including myself), and code patterns, before their data and as a result a lot of things end up being harder than they need to be. I've always liked this quote from Torvalds on the subject speaking on git's design (first line is for some context): > … git actually has a simple design, with stable and reasonably well-documented data structures. then continues: > In fact, I'm a huge proponent of designing your code around the data, rather than the other way around, and I think it's one of the reasons git has been fairly successful […] 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. When I have good data structures most things just sort of fall into place. I honestly can't think of a time where I've figuratively (or literally) said "my data structure really whips the llamas ass" and then immediately said "it's going to be horrible to use." On the contrary, I have written code that is both so beautiful and esoteric, its pedantry would be lauded for the ages-- had only I glanced over at my data model during my madness. No, instead, I awaken to find I spent my time quite aptly digging a marvelous hole, filling said hole with shit, and then hopping in hoping to not get shitty. One thing that really has helped me make better data structures and models is taking advanced courses on things like multivariate linear regression analysis specifically going over identifying things like multicolinearity and heteroskedasticity. Statistical tools are incredibly powerful in this field, even if you aren't doing statistical analysis everyday. Making good data models isn't necessarily easy, nor obvious, and I've watched a lot of experienced folks make silly mistakes simply because they didn't want something asinine like two fields instead of one.
- dexen 6y agoIt's worth noting the same holds true for UI: data dominates. Design your widgets, layout, and workflow around the data.
- chrisweekly 6y ago
- OliverJones 6y agoIn long-lived systems (systems that run for many years) it's almost impossible to choose the "right data structures" for the ages. The sources and uses of your data will not last nearly as long as the data itself. What to do about this? Two things: STORE YOUR TIMESTAMPS IN UTC. NOT US Pacific or any other local timezone. If you start out with the wrong timezone you'll never be able to fix it. And generations of programmers will curse your name. Keep your data structures simple enough to adapt to the future. Written another way: respect the programmers who have to use your data when you're not around to explain it. And, a rule that's like the third law of thermodynamics. You can never know when you're designing data how long it will last. Written another way: your kludges will come back to bite you in the xxx.
- aserafini 6y agoSometimes storing in UTC is simply not correct. For example a shop opening time. The shop opens 10am local time, whether DST or not. Their opening time is 10am local time all year but their UTC opening time actually changes depending on the time of year!
- wvenable 6y agoI made that mistake early my career following this exact advice and I ended up with a lot things were randomly 1 hour off depending on when the record was created and the date entered.
- Benjammer 6y agoTotally. "Store everything in UTC" is just another flavor of "pick a timezone to store everything." In a lot of cases, you probably need to go ahead and just store the fully qualified date including timezone/offset for each record.
- account42 6y agoEven storing offset or timezone might not be enough if what you really want is some future date and time at a particular location. Timezones do change, including the regions they cover. Still, for things that have already happended, storing them as a UTC timestmp is almost always the correct thing to do.
- dang 6y agoIf curious see also 2017 https://news.ycombinator.com/item?id=15265356 https://news.ycombinator.com/item?id=15265356, https://news.ycombinator.com/item?id=15776124 https://news.ycombinator.com/item?id=15776124 2014 https://news.ycombinator.com/item?id=7994102 https://news.ycombinator.com/item?id=7994102 Pete_D gets credit for the date: https://news.ycombinator.com/item?id=15266498 https://news.ycombinator.com/item?id=15266498. These rules come from "Notes on Programming in C" (http://www.lysator.liu.se/c/pikestyle.html http://www.lysator.liu.se/c/pikestyle.html), which has its own sequence of threads: 2017 https://news.ycombinator.com/item?id=15399028 https://news.ycombinator.com/item?id=15399028, https://news.ycombinator.com/item?id=13852734 https://news.ycombinator.com/item?id=13852734 2014 https://news.ycombinator.com/item?id=7728084 https://news.ycombinator.com/item?id=7728084 2011 https://news.ycombinator.com/item?id=3333044 https://news.ycombinator.com/item?id=3333044 2010 https://news.ycombinator.com/item?id=1887442 https://news.ycombinator.com/item?id=1887442
- gentleman11 6y ago> Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident What does this have to say about the careers and roles of data scientists vs programmers? A data scientists entire job is to categorize and model data in a useful way. In the future, will they fundamentally more important than coders, or will the two roles just merge?
- ttamslam 6y agoI think you're conflating two things: in my mind, working on the shape of data is different than pulling inferences out of that data.
- gridlockd 6y agoAll this advice against "premature optimization" has created generations of programmers that don't understand how to use hardware efficiently. Here's the problem: If you profile software that is 100x slower than it needs to be on every level, there are no obvious bottlenecks. Your whole program is just slow across the board, because you used tons of allocations, abstractions and indirections at every step of the way. Rob Pike probably has never written a program where performance really mattered, because if he did, he would've found that you need to think about performance right from the beginning and all the way during development, because making bad decisions early on can force you to rewrite almost everything. For instance, if you start writing a Go program with the mindset that you can just heap-allocate all the time, the garbage collector will eventually come back to bite you and the "bottleneck" will be your entire codebase.
- byronr 6y ago> Rob Pike probably has never written a program where performance really mattered Rob Pike has written window system software which ran in what now would be called a "thin client" over a 9600 baud modem and rendered graphics using a 2MHz CPU. He probably knows a thing or two about performance tuning.
- gridlockd 6y agoBy "rendered graphics" you mean "place characters on screen"? If the bottleneck for that is a 9600 baud modem throughput, there's not a lot you need to optimize, even on a 2MHZ CPU. Also, having programmed more constrained systems decades ago doesn't magically make you knowledgeable on performance on modern hardware with completely different capabilities. In fact, it's probably what causes you to develop a "computers are so fast now, no need to think about performance"-mindset, because everything you want to do could be done in an arbitrarily inefficient way on modern hardware. Performance doesn't matter to you anymore.
- zimpenfish 6y ago> By "rendered graphics" you mean "place characters on screen"? It was a fully graphical 800x1024 (or 1024x1024) system running on 1982 processors. https://en.wikipedia.org/wiki/Blit_(computer_terminal) https://en.wikipedia.org/wiki/Blit_(computer_terminal) > having programmed more constrained systems decades ago doesn't magically make you knowledgeable on performance Perhaps not but it does mean you've "written a program where performance really mattered" which I believe was the original claim?
- ed_elliott_asc 6y agoWhen people say worry about the data structures, what do they mean?
- RcouF1uZ4gsC 6y agoOne of the big problems with fancy algorithms is that they either access data out of order and/or do pointer chasing. Simple algorithms tend to access the data in order. CPU's have a lot of logic for making in order data access very fast.
- dkarl 6y ago> Rule 1. You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is. I wish people would follow this rule and just let stuff work. I recently encountered the most extreme version of this I've ever seen in my career: a design review where a guy proposed a Redis caching layer and a complex custom lookup scheme for a <1GB, moderate read volume, super low write volume MySQL database. And of course he wants to put the bulk of the data in JSON fields and manage any schema evolution in our application code. Can't we just let stuff work? I'm no fan of MySQL, but can't we admit that a ubiquitous and battle-tested piece of technology, applied to a canonical use case, on tiny data under near-ideal circumstances, is probably going to work just fine? At least give it a chance before you spend days designing and documenting a bunch of fancy tricks to save MySQL from being crushed under a few megabytes of data.
- maxk42 6y agoThis is particularly exasperating for me. I can't tell you how many times in my professional career I've ended up speeding up systems by removing two or three layers of improperly-implemented "caching" and using good ol' MySQL and a basic understanding of algorithmic time complexity to simplify things.
- flukus 6y agoMe too. I've seen a few systems that replaced their simple request requiring 10,000 queries "optimized" by requiring 10,000 cache lookups when they should have just added some joins. The bottleneck is the network latency, not the database. The worst I've seen is an nHibernate cache stored in a session variable, half the database was being serialized/deserialized on every http request. Fortunately that was a small database. Even with in memory caches I've seen systems grind to a halt by death of a thousand cuts, dictionary based entity attribute systems where each attribute is looked up individually. There seems to be a mentality that constant lookup == free lookup and devs don't seem to realize that constant * $bignumber == $biggerNumber. Caching shouldn't be granular. Obligatory latency numbers every programmer should know: https://gist.github.com/jboner/2841832 https://gist.github.com/jboner/2841832
- munificent 6y ago> Rule 1. You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is. I agree with the general thrust of this. But it's worth pointing out that often the easiest way to prove where a bottleneck is (or at least) isn't, is to try an optimization and see if it helps. I like profiling tools immensely, and this kind of trial an error optimization doesn't scale well to widespread performance problems. But there's something to be said for doing a couple of quick optimizations as tracer bullets to see if you get lucky and find the problem before bringing in the big guns. The last three rules bug me. I wish we had a name for aphorisms that perfectly encapsulate an idea once you already have the wisdom to understand it, but that don't actually teach anything. They may help you remember a concept—a sort of aphoristic mnemonic—but don't illuminate it. The problem with these is that espousing them is more a way of bragging ("look how smart I am for understanding this!") than really helping others. For example: > 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. OK, well what are the "right" data structures? The answer is "the ones that let you perform the operations you need to perform easily or efficiently". So you still need to know what the code is doing too. And the algorithms are only "self-evident" because you chose data structures expressely to give you the luxury of using simple algorithms.
- wtetzner 6y agoI think the point is more to direct how you write/refactor code: focus more on the data structures than on the code. E.g. if you're struggling to write the code, then maybe you need to take a step back and reconsider your data structures.
- glangdale 6y agoThese rules are good as far as they go. However, they are notably silent on what happens when they stop working. If you're a celebrity computer scientist and a problem has been 'squashed' to the point where there aren't any more 80-99% "hot spots" I guess you can just parachute out of there and on to a more interesting problem. However, if you're paid to work on a particular thing, sooner or later, you will fire up a profile and say "oh, great, I don't have a hot spot anymore, just a bunch of 10-30% 'warm spots'". At that point you need to attack problems that aren't traditional bottlenecks if you still want to get speedups. Moreover, the things that you learn from repeatedly attacking those 10-30% 'warm spots' might be fundamentally different from the learning you get from, I dunno, taking some O(N^2) monstrosity out of the "99% of the profile" and Declaring Victory.
- badrequest 6y agoThere are actually six rules!
- combatentropy 6y agoThere is no Rule 6 --- http://doc.cat-v.org/bell_labs/pikestyle http://doc.cat-v.org/bell_labs/pikestyle
- bob1029 6y agoModeling the problem domain is so important that I dont know why the first year of every compsci undergrad program isnt entirely dedicated to teaching the idea. Instead, day 1 is installing python or java, running hello world and talking about pointers, binary, encoding, logic gates, etc. We should be teaching students on day 1 that code is a liability and to be avoided whenever it is convenient to do so.
- codemonkey-zeta 6y agoIMO Matthias Felleisen (building on work of Sussman (IIRC) et. al.) gets first-year CS education right with How to Design Programs (https://htdp.org/2020-5-6/Book/index.html https://htdp.org/2020-5-6/Book/index.html). Literally step 1 in the design recipe presented in the preface is: "1. From Problem Analysis to Data Definitions Identify the information that must be represented and how it is represented in the chosen programming language. Formulate data definitions and illustrate them with examples."
- pjettter 6y agoI recommend Domain Modeling Made Functional by Scott Wlaschin. It's analaysis first, DDD, then coding (in F#) Best intro to functional programming imo.
- GuB-42 6y agoRule 1. You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is. True, but emphasis on the speed hack. It shouldn't stop you from thinking about performance in your design. If it means doing less, do less now. If it means adding a speed hack (usually some sort of cache), don't do it until you are sure that you need it. Rule 2. Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest. I agree completely. But you have to realize that measuring is as much of an art form as optimization is. Especially on today's ridiculously complex systems, the bottleneck may not be obvious. For example a function may take a long time to run, but the real cause may be another function flushing the cache. Rule 3. Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don't get fancy. (Even if n does get big, use Rule 2 first.) Disagree, unless you can prove that n will stay small. You don't know how your users will abuse your program. For example, you may have designed your program to handle shopping lists of a few dozens of items, and then someone decides to import the entire McMaster-Carr catalogue, which has more than half a million items. It may be a great use case you didn't thought of, and that fancy algorithm permits it by scaling well. There are also vulnerabilities that exploit high algorithmic complexity and worst cases. Don't overdo it, but N^2 is rarely a good idea if you can avoid it. Rule 4. Fancy algorithms are buggier than simple ones, and they're much harder to implement. Use simple algorithms as well as simple data structures. True, but with the caveats of Rule 3 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. Agree, for me there is a hierarchy in code. From most important to least important: data (structures), code (algorithms), comments. The order comes from the fact that if you change your data, you need to change your code too, and if you change your code, you also need to change your comments. Going the other way, you can freely change comments, and changing your code will not require you to change your data. Data is the cornerstone.
- 4thwaywastrel 6y agoI feel ike #5 is why many people like GraphQL, and #1 - #4 is why many hate it. It becomes much easier to understand what data exists and build tools on top of it's schema. But the extra cludge it adds to optimise the specific case of returning less data in a field is often counter productive.
- pier25 6y ago> But the extra cludge it adds to optimise the specific case of returning less data in a field is often counter productive. Could you elaborate?
- radmuzom 6y agoWhile the rules make sense, it is often not realistic due to business constraints. What tends to happen in real life is that the profiling and optimization of bottlenecks is forgotten once the software is "ready". I would propose Rule 0: Developers are irrelevant, only end users of your software matter.
- combatentropy 6y agoA quote that combines the rules about optimization with the rules about data structures: "NoSQL databases that only have weak consistency are enforcing a broadly applied premature optimization on the entire system." --- Alexander Lloyd, Google Also in support of Rule 5, see Eric Raymond's treatment of Data-Driven Programming: "Even the simplest procedural logic is hard for humans to verify, but quite complex data structures are fairly easy to model and reason about. To see this, compare the expressiveness and explanatory power of a diagram of (say) a fifty-node pointer tree with a flowchart of a fifty-line program. Or, compare an array initializer expressing a conversion table with an equivalent switch statement. The difference in transparency and clarity is dramatic. See Rob Pike's Rule 5. "Data is more tractable than program logic. It follows that where you see a choice between complexity in data structures and complexity in code, choose the former. More: in evolving a design, you should actively seek ways to shift complexity from code to data." http://www.catb.org/~esr/writings/taoup/html/ch01s06.html#id2878263 http://www.catb.org/~esr/writings/taoup/html/ch01s06.html#id... http://www.catb.org/~esr/writings/taoup/html/generationchapter.html http://www.catb.org/~esr/writings/taoup/html/generationchapt...
- johndoe42377 6y agoThis is even more relevant after 30 years. The Data Dominates principle is the key, everything else just follow, including n are usually small and preference for simple algorithms. Nowadays we have exactly the opposite, which is understandable since the field has been invaded by uneducated amateur posers. https://karma-engineering.com/lab/blog/NodeModules https://karma-engineering.com/lab/blog/NodeModules
- deleted 6y ago[deleted]
- okaleniuk 6y agoJust yesterday I removed an obsolete doxygen tag from some 300 files and my Visual Studio went catatonic. Well, I suspect it's not about Studio per se but rather the git integration but still. Someone avoided a "fancy algorithm" and wasted both my time and the product reputation with a "small n" workaround. Because, git is about small commits right? I'd like to restate the first rule as "You can't tell where a program is going to spend its life".
- zekrioca 6y agoWhy don’t interviewers at tech companies just don’t follow these rules while grading candidates?
- HeavyStorm 6y agoWait, wasn't Knuth that said that premature optimizations are the root of all evil?
- spirographer 6y agoRob Pike's rules of programming simplified : - Start with stupid code built on smart data (after Fred Brooks) - When in doubt use brute force (Ken Thompson) - Premature optimization is the root of all evil (Tony Hoare)
- Impossible 6y agoRule 5 (data dominates) is exactly the same as lie 3 (code is more important than data) of Mike Acton's Three Big Lies (https://cellperformance.beyond3d.com/articles/2008/03/three-big-lies.html https://cellperformance.beyond3d.com/articles/2008/03/three-...). Rob Pike's rule 3 (don't use fancy algorithms) is closely related to Mike Acton's lie 1 (software is a platform) as well. A part of me wonders if Mike was influenced by Rob Pike's rules directly or indirectly. It's also something that an experienced programmer can discover independently easily enough. Mike Acton was clearly heavily influenced by some of the failures of classic OOP design (lie 2 of Three Big lies).
- rswail 6y agoOver time, the rule I've "discovered" is: "Focus on the Nouns, not the Verbs"