15 ms·
Rob Pike’s Rules of Programming (1989)
- hardkorebob 3y agoGreat format. Love easy to view fast pages. Great advice too for the true hacker. Today the advice goes well but only for a small, tiny niche group. What is considered today as mainstream programming is so abstracted that speed of an algorithm is not a concern on anyone's plate when they fire up an Electron app.
- lowq 3y agoOne might say Electron's algorithmic constant is quite large..
- gfiorav 3y agoMany of these guidelines essentially boil down to strategies for preventing over-engineering. I concur; in my experience, premature optimization is one of the most expensive pitfalls. This primarily stems from the fact that circumventing potential issues too early leaves them unchallenged, resulting in the next team having to devise expensive solutions to address the unnecessary complexity. The approach that was instilled in me is this: optimizations rely on presumptions, and these presumptions are often incorrect in the beginning. Additionally, I've discovered that managing ego and understanding psychology play crucial roles in dissuading individuals from creating overly complex code.
- vrosas 3y agoI like to say, “solve problems you have, not problems you think you have.”
- deleted 3y ago[deleted]
- arethuza 3y agoYAGNI: https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it
- vrosas 3y agoSort of, but people get defensive and start to argue that they _will_ need whatever it is at some point. But my argument is that, fine, you may be right, but if it's not needed _right at this very moment_ there's no reason to rush it in. Often the best way to prepare for the future is to do as little as possible - keeping things simple now makes adaptions much easier down the road if and when the need actually arises.
- deleted 3y ago[deleted]
- digbybk 3y agoOur future selves will always have more information than our present selves, so we should let them make the decision whenever possible.
- kvmet 3y agoThis concept is also in-line with Lean/Six-Stuff and identifying "wastes". Overproduction (analogous to over-engineering) is usually considered the worst type of waste because not only are you making something you don't need, you're spending effort that could have been used on something that you _do_ need.
- goto11 3y agoAnd digging a step deeper: Over-engineering often happen because you think you might need the complexity later, but it will be more difficult or risky to extend the system at a later time. E.g. starting out with a microservice architecture even though you only have 100 users, because you think it will be too difficult to re-architect a monolith the day you hit a million user. So you should address why it feels like the code becomes less malleable over time.
- m463 3y agoSomeone I know said - don't get fancy with errors. fail early and simply.
- no_wizard 3y agoI love this >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 completely agree with this. Which is why all the LeetCode interviews always struck me as odd. They focus on algorithms, not data structures, which is exactly what you don't want to do out of the gate, most of the time. I suppose, if you don't know algorithms at all you wouldn't realize when it is either A) an exception to the rule or B) A time where you need to lean into specific algorithm for X, Y or Z reason However, you can teach algorithms in relatively short order, I have honestly found people grok which data structures to use less easily, though its all anecdotal
- dzonga 3y agomy algorithms D/S professor told me one trick. always use a 'map'. works for most cases.
- bitwize 3y ago"Show me your flowcharts, but keep your tables hidden, and I shall continue to be mystified. Show me your tables, and I won't need to see your flowcharts, they'll be obvious."
- kwhitefoot 3y agoYou forgot the credit: Fred Brooks, Mythical Man Month,
- jrpelkonen 3y agoGreat quote and so true in the general case. Unfortunately, I have seen some database designs that have left me more mystified than I was before.
- capableweb 3y agoI've seen programs that got more mystical the more the employees showed me how it worked internally.
- ndr 3y agoHow does one go from > 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. to > Rule 5 is often shortened to "write stupid code that uses smart objects". "smart objects" left such a bad taste in my mouth, the original rule is so much better albeit lengthier.
- dbalatero 3y agoSeems pretty clear to me, what issue are you having?
- sowbug 3y agoWrite code that naturally follows from well-structured objects.
- cgdub 3y agoI think Rob Pike would agree that "smart objects" is the wrong way to think about it: https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html https://commandcenter.blogspot.com/2012/06/less-is-exponenti...
- lowq 3y agoAgreed. I find that "smart objects" are much more difficult to make cohesive with one another. Punting your "smart" logic to a higher level is easier to understand, test, and change.
- lkjflakjsdeowe 3y agoSigh, here we go again. > Tony Hoare's famous maxim "Premature optimization is the root of all evil." It's actually from Donald Knuth and this quote is frequently taken out of context to argue against optimization in general. Here is the entire quote "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%." The point is to spend time optimizing where it will have impact.
- karmakaze 3y agoKnuth attributes it to Hoare, and Hoare attributes it to Knuth. So it come's down to who you want to believe. Probably best to attribute it to both. My guess would be that Tony said it first, Knuth refined and printed it. It's always good to have the longer quote which gives needed context.
- eesmith 3y agoHoare attributed it to Dijkstra. See https://hans.gerwitz.com/2004/08/12/premature-optimization-is-the-root-of-all-evil.html https://hans.gerwitz.com/2004/08/12/premature-optimization-i... . "I’m sorry I have no recollection how this quotation came about. I might have attributed it to Edsger Dijkstra."
- karmakaze 3y agoSomeone needs to make a Spider-man meme with the quote.
- zelphirkalt 3y agoMaybe it is in the end a secret deal between them, to have a joke about circular references. ; )
- preommr 3y agoAlso people forget that quote is from the 70s. Almost 50 years go. Programming used to be very different from what it is now. "Premature optimization" wasn't "hey just use this popular lib cause it scales", it was "let's use some impossible to understand bit fiddling algorithm that only works on this piece of hardware".
- ttfkam 3y 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. This goes double for databases. Folks who use a DB as a dumb bit bucket or a simple 1:1 reflection of their object definitions are often surprised when the DB takes it personal and dooms performance. If I ever see another ORM-generated DB schema it'll be too soon.
- mrweasel 3y ago> If I ever see another ORM-generated DB schema it'll be too soon. I'd argue that most ORMs generate the schema you ask it to. Using an ORM isn't going to create a worse database layout that you could do by hand. The issue is that some/many developers don't know SQL, nor have the required knowledge of their databases to use an ORM. The ORM requires you to know what lies underneath, it is a fairly leaky abstraction. Understanding that, you can get most ORMs to create nice schemas.
- ttfkam 3y agoORMs are typically lowest common denominator for compatibility with many database engines. The best thing you can do is learn about the underlying engine (Postgres, MySQL, MS SQL Server, SQLite, etc.) and its distinct feature set. Once you know that, you will often find yourself quite a ways away from the lowest common denominator. That may be built in temporal table support in MS SQL Server or MariaDB, so you don't need explicit audit tables in your schema. Or perhaps timestamp ranges with exclusion constraints in Postgres for enforcing valid schedules without hacks in the app layer. Eventually you notice that you're having to define everything twice: once for the DB and again for the ORM definition. This is why I prefer solutions like PostgREST, Postgraphile, and Hasura (for Postgres while other DBs have other similar solutions). Define it once in the DB and just let it bubble up. You may want to expose your storage API through views, but it still ensures optimal data structure at the foundation. DB -> data-generated API service -> client API codegen -> client app such as web or mobile. With a typical ORM, you're building from the middle out. It almost always results in a faulty foundation. Pour and set the foundation first. Always. https://postgrest.org/ https://postgrest.org/ https://postgraphile.org/ https://postgraphile.org/ https://hasura.io/ https://hasura.io/
- IshKebab 3y agoBad advice IMO. Not because it's wrong - it mostly isn't - but because people will hear it and think "ah I don't need to consider performance at all until... later". His first people is not technically wrong but it is highly misleading. Sure you can't know which bits of a program are going to be slow without measuring, but that doesn't mean you have no clue at all. You can often make a very good guess!
- avg_dev 3y agowow, I didn't get that impression at all. And he clearly does say "Measure", not "shut off your brain". I would assume that if you measure enough things and code enough you may start to get a feel for what is going to be expensive and what is not. And then - as before - you can continue to measure and iterate. (Also, I think you said "first people" when you meant "first point")
- IshKebab 3y ago> And he clearly does say "Measure", not "shut off your brain". Yes but he doesn't say that if you don't measure (which most people won't) then you should still engage your brain. That's the missing point. Measuring is typically more effort than applying a little brain power and experience. So the choices shouldn't be "measure or nothing", but that's how people always interpret it.
- shadowgovt 3y agoThe key thing that drives rule 1 and 2 is the assumption in rule 4: all other things being equal, terser code is easier to work with. The cheapest code to maintain is the code that doesn't exist. Therefore, given a choice between writing a little code to make the program work or writing a lot of code to maybe make the program work faster... Write a little code and go back and write the longer code iff it will actually help performance as per measurements. You're better off expanding a simple skeleton than moving bones around in an already-complex assembly.
- 3y ago
- alkonaut 3y agoMy additional rule: tiny bits of wasted perf will accumulate and eventually make the program slow even though each one doesn't cost much. So don't leave perf on the table so long as complexity/readability/maintainability/implementation cost isn't affected. That is: all else being mostly equal, it's not OK to choose the slower of two options. Also: if you assume your N's are small then you can get away with almost anything. But if you write a piece of code that is going to work well for N below 100, but suck for N over 10000 Say, anything with O(N^2), then just cap it. Make a big fat error if the small N assumption breaks. It's still better than the AWS bill surprise or hung program or whatever it could be otherwise.
- cratermoon 3y ago> tiny bits of wasted perf will accumulate and eventually make the program slow even though each one doesn't cost much Rules 1 and 2 apply here, though.
- alkonaut 3y agoIf you spend 100ns you spend 100ns. It doesn't matter if it's in a bottleneck or not. Note that this of course assumes that spending 100ns anywhere is actually making the program and user _wait_ 100ns, i.e. it assumes we are cpu bound all the time. For any program that does I/O this wouldn't be the case. A "bottleneck" is going to be a network request, and for much of the programs execution time you can just make the CPU do anything without the user even noticing. So this argument is based on CPU bound interactive programs, which isn't all programs. In programs with e.g. IO (which would be most) then rules 1+2 would come along. But I guess the thing is that in an interactive CPU-bound program like a game, there _is_ one single bottleneck and most of the code is on that hot path. It's pretty easy to establish that you are in the bottleneck: it's when you are writing per-frame code.
- jd3 3y agoI first read this on cat-v 10+ years ago and it left an indelible effect on the way that I approach and think through both design and complexity http://doc.cat-v.org/bell_labs/pikestyle http://doc.cat-v.org/bell_labs/pikestyle
- epiccoleman 3y ago> 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.) Another point on this, which I really saw in action on a recent project - a "big" n is probably much bigger than you think. Sometimes it can be easy to think "oh, this is going to have to do 100,000 operations, I definitely need to optimize it" - but computers are fast, and 100,000 multiplications (for example) happens so fast you probably don't need to think too hard about it. That's not to say you shouldn't think at all, just that it's often surprising how insanely fast modern computing hardware is.
- nine_zeros 3y agoI also keep seeing leetcode interview problems about iterating over a list of 100k items a few times. I can see that it is not optimal but iterating over 100k items is NOTHING compared to the network call you made right after that iteration - in terms of actual production time. And every time I interview, the hiring managers want me but my hiring decision gets vetoed by a leetcode newbie who hasn't experienced production scars yet.
- deleted 3y ago[deleted]
- diarrhea 3y agoIn an async framework of execution, this doesn't apply. A lot of programming happens in that space, and in it, the network call is "free", but you're clogging the thread(s) with actual CPU work. If execution is single-threaded, the problem becomes very relevant, but it applies to multi-threaded async just the same (you might exhaust the pool of workers). Keeping this in mind isn't esoteric either, as it applies to JavaScript, Python, Rust, C#, and probably others.
- nine_zeros 3y ago> In an async framework of execution, this doesn't apply. That's right. Async execution prevents the IO from being the bottleneck by offloading it to a different thread. There are 3 situations where this statement falls apart: 1. If the execution is single threaded, as you rightly pointed out 2. If the response of the async execution matters to the final response of your service. In this case, the primary thread may finish its work but its still waiting for IO to complete. Basically making it synchronous but using async primitives. 3. The CPU utilization of iterating over 100k items in a list is negligible compared to the hundreds of daemons and services running on the host. Even a docker container will utilize more CPU than iteration over 100k items. The point is: over-indexing over iteration and time-complexity in interviews is pointless as real systems are going to face challenges far beyond that.
- frou_dh 3y agoThen when he designed Go he made the act of data modelling akin to having one hand tied behind your back, because it supports only product types and not sum types too.
- MarkMarine 3y ago[flagged]
- ikari_pl 3y agoThey also made sure you can't easily tell what the code is doing due to the noise of edge case handling in 75% of the lines
- cratermoon 3y agoBuggy "edge case handling" is the source of many critical failures[1]. Go makes explicit where a called function can return and also provide information for any anomalous conditions encountered. The alternative of just pretending like a return means success is wrong, and other ways to determine if the result of called function is acceptable (e.g. checking errno in C) are just as verbose and introduce other failure modes. Here's a thought experiment for you: pretend the return type is something other than 'error': result, statuscode, responseContext, anything that doesn't imply failure. Would you then suggest handling that is "noise"? ETA: "there are countless other [than if err != nil] things one can do with an error value, and application of some of those other things can make your program better, eliminating much of the boilerplate that arises if every error is checked with a rote if statement."[2] 1 https://www.eecg.utoronto.ca/~yuan/papers/failure_analysis_osdi14.pdf https://www.eecg.utoronto.ca/~yuan/papers/failure_analysis_o... 2 https://go.dev/blog/errors-are-values https://go.dev/blog/errors-are-values
- golergka 3y agoAlternative is using result or either monad and have first-class support for nomadic operations in the language so you don't have to waste three lines on every function call just to propagate the error up
- boredumb 3y agoMay not be very popular of an opinion, but rule #1&2 have been used as a crutch to create bloatware and slow as dogshit software that is always dismissed under a guise of someone is going to find the time to retroactively implement some tracing and introspection system and then rewrite portions of the application in magically isolated interfaces that will make the slow POC fast. It very rarely happens and is usually in the form of a complete rewrite that is forced onto a short timeline so.... you can't possibly be so new as to prematurely optimize! (just rewrite it in a new stack it will solve it somehow) *edit to offer something less whiney I think optimizations that rely on specific non-core business rules are a root of evil - but you should still be properly indexing your queries, not doing them in loops, trying to make parallel work run in parallel, not write a ton of junk over the wire when ever you can, be conscious of nesting any loops and generally the best optimization is even listed: choosing the correct data types for a problem.
- arp242 3y ago> you should still be properly indexing your queries, not doing them in loops, trying to make parallel work run in parallel, not write a ton of junk over the wire when ever you can, be conscious of nesting any loops and generally the best optimization is even listed: choosing the correct data types for a problem. I don't think anyone disagrees with that, but the indexing is a good example of "measure, don't assume" because SQL engines can do surprising things, and the best way to know what to index is just to measure (and sometimes no index is actually best!) And "completely pretend performance is not a thing" is of course the other extreme from "optimise everything from the get go". Unfortunately there are always people who these sort of "rules", "laws", and "best practices" as cudgels to beat other arguments with, rather than some loose commentary (which is usually what it is). Previous comment: https://news.ycombinator.com/item?id=36417264 https://news.ycombinator.com/item?id=36417264
- abtinf 3y agoEnlightenment comes from understanding that they are all the same rule.
- justincredible 3y ago[dead]
- marcosdumay 3y agoMost of those are bad. I don't know why people keep rewriting and perpetuating those rules. For #1 and #2, well you should know beforehand. Don't you know what your software does? The details of how the time is spent surely will be surprising, and there may be a hidden bomb here or there, but if you can't see from the requirements where most of the time will be spent, you have a problem that you should work on fixing. Of course, that doesn't mean you should go and optimize it. You should have an idea of your implementation performance before writing it, and you should be able to tell if it's acceptable. But heavy optimization does need profiling. People are repeating that bastardization of the "avoid premature optimization" for decades. Go follow the original, with its nuance; those generalizations are trash. On rules #3 and #4, the fancy algorithm is usually already written and well debugged. Go use it. The performance when n is small usually doesn't matter. If it's not written, then go read the thing about optimization. You should know how big n will be. If you don't know, ask around. Rule #5 is the only one that actually stands without much nuance. There are exceptions, but not many.
- eschneider 3y agoAs for #1 and #2, you really DO need to measure. Over the years I've spent a lot of time optimizing other people's code and many performance problems are quasi-bugs. Doing things like inserting data into sorted data structures (as opposed to doing all your inserts and THEN sorting) aren't so much "This is an obvious hot spot from the problem definition" as "A poor decision made this a hot spot." Profiling finds this sort of low hanging fruit quite easily.
- marcosdumay 3y agoSo, you had a performance bomb somewhere. That doesn't change the fact that you know beforehand what kind of problem takes a lot of CPU time and what doesn't. Profiling doesn't find things of the kind of "this takes a lot of computer time, we should program everything around it"; "this takes a lot of computer time, are you sure we can run it profitably?"; or "this takes a lot of memory, are we willing to get new servers?". Besides, the worst moment to optimize your code is after everything is written and people depend on its interface. Profiling is some duck tape you can use to cover small problems, and mostly only that.
- travisgriggs 3y 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. Isn’t this a plug for some sort of object oriented programming? Or at least highly structured programming? Interesting in today’s trendy clime of “objects bad/passe, function(al) good.” Having done quite a bit of OOP where “binding behavior to data” is the thing in an ideal laboratory for it (Smalltalk and others), I gained some experience with watching people do this. I observed that there were plenty of good ideas across the industry on how to model data (inheritance, prototype, classification, mixins, mutability,etc), but what I observed is that which data groups together well is very much an art, and that was where people struggle to succeed with the data centric emphasis. The easy objects/structs are of course easy, Point, Rect, Person. But as the data got more complex, getting people to come up with good boundaries gets more and complex quickly, and you ended up with really poor object constitutions. Reification is hard. I don’t think it is impossible, I’ve seen people who have a knack for reification come in a refactor an object soup into a cluster of data structures that was beautiful. But yeah, good reification I fear is as much an art as science.
- softfalcon 3y agoI find the statement is true for either object oriented or functional programming. As someone who has done both extensively, I find that the patterns are still applicable to both. The presentation is very different, but still viable. For instance, you might use recursion to traverse data over a for-loop, but that doesn't inherently change the concept of a data "structure". No matter what, we're still speaking in design patterns and if we share that common language, we can apply it to a domain and solve the larger problems of our day-to-day. If you want more examples of this, look up Data Driven Development, but also append Haskell or C++ to your search queries, you'll find they repeat the same concepts in two very different "grammars"... ahem... I mean "languages".
- travisgriggs 3y agoYes, given the downvotes, I fear my comment may be misconstrued as a function(al) bash. I write lots of Elixir these days. And see the same issues. All I was trying to say is that, my experience in OOland, that was hyper focused on this idea, gave me lots of opportunity to see that while this rule is obvious and good and everyone wants to do it, I observed that for many programmers decomposing complex data structures is a very non-intuitive task, and difficult to actually realize this rule.
- quelsolaar 3y agoGenerally these are good, but in practice #1 doesn't hold. When you start out you need to have a _theory_ about what will be you bottleneck. A lot of times you cant implement XYZ, and then measure what was slow and fix that. X, Y, and Z are connected and sometimes you need to build X and Z in a specific way, just so that Y can be made fast, and you know that Y is going to be the bottle neck. Later, when you do measure and know for a fact what is slow, you still have to make a bet on an approach that will make it faster. The more educated you bet is the better. Good programmers measure, but good programmers have to litterate less because they can predict what will be slow, buggy, use too much memory, and make educated bets in advance, that avouid issues. If you start saying that its a rule that you cant predict performance behaviour, then you are dismissing a lot of experience and skills that good programmer accumulate.
- mumblemumble 3y agoIn practice, #1 is an iron rule for people who don't believe it, and a loose guideline for people who do. Because observing rule #1 happens to be the best way to get the experience and empirical background that are necessary to develop a good intuition for where to expect bottlenecks.
- e12e 3y agoCould you give a few concrete examples? I'm doubtful it makes a difference in most cases? If you're building a new system, from new requirements - often just getting started is fine? Build, test/measure, throw-away/refactor - repeat? Take rust as an example - start with a draft language, a compiler in ocaml. Iterate. (I concede that Hoare might have known the project might move from ocaml to self-hosted at some point - but I'm not sure that makes much of a difference?)
- quelsolaar 3y agoSure, Right now I'm working on a Constructyive Solid Geometry algorithm, it requires me to cast a lot of rays, so i know this will be slow. I can up-front say that the Raycaster needs to have fast data structure and that its worth giving up some performance to set that data up correctly. I also know it needs to be multithreaded, so thinking up front about how to manage that is a given too. A lot of times, I try to count the zeros. If im doing anything over the network, its going to be miliseconds, but if i do something with memory its going to be nano seconds, so optimize to take remove network requests. If i work on a problem that is multi threaded, i need to conside what can be multi-threaded and what can not. Can i minimize the stuff that cant be multi-threaded, and is there other work to be done while waiting for things that cant be multi-threaded? A lot of times I consider latency vs bandwidth. I know that Latency will always be a harder problem, and a problem hardware has harder time solving, so I try to design for low latency first, and then worry about bandwidth. These are all architectiual decission, that are made early and have a big impact. They are VERY expencive to change, so you want to be as right as you can be the first time. If one part turns out to be slow you can profile and work on it, but changing the struecture of how the program operates and how data is stored and flows is much harder. The author is right, that data structures are the most important tool for optimization. Especially on modern hardware where cache misses are so expencive. The problem is that _everything_ depends on your data structures, so changing them is a lot of work. (I was just at the blender conference where there was a talk about changing the mesh structure from arrays of structs, to structs of arrays, and it took them two years to make this simple change)
- tomxor 3y agoThese are all correct and good advice, but I suspect most people misinterpret "avoid premature optimisation" style advice as "don't bother to write efficient code". Caring about basic efficiency, and being thoughtful about compute is _not_ the same as premature optimisation. This kind of wastefulness in modern software is what causes death by 1000 cuts style inefficiency, it's not because we aren't optimising, it's because we are wasting.
- bluGill 3y agoI call this premature pessimization. Often we know of the best algorithm, so not using it is wasteful. Often not making many copies is easy in the language but we do it anyway.
- fasterik 3y agoI think the wastefulness comes from people imposing a top-down structure on the code before they have a working system. If you first write stupid simple code that solves the problem, then identify areas that need to be faster, you won't have layers of abstraction getting in the way of optimizing it.
- TheRealPomax 3y agoUnfortunately, Rob didn't stipulate what "fancy" means. For instance: A* is definitely fancy, but it's neither buggy nor particularly hard to implement. And because of what it solves, there isn't even a simple alternative to it. I'd probably replace "fancy algorithms" with "self-invented algorithm" instead: you're not solving a new problem, resist the urge to "tackle it yourself" and just look up the almost-certainly-decades-old, and documented-by-thousands-of-people algorithm that's going to get the job done. (Of course, that'll be less fun for you, but if the only person who appreciates a piece of code you wrote is you, that's one of the signs that you wrote bad code.)
- firefoxd 3y agoOn my first Amazon interview, I'm pretty sure I bombed because I brute forced the algorithm question. In the real world, when we have an issue on production, I fix it first, then find a solution. Meaning in that first hour customers are complaining, I'm not gonna try to create a fancy algorithm that can handle all cases. I'll make it work with nested loops if need be. Then I can sit down and figure out a permanent and elegant solution.
- nevir 3y agoFWIW, that's typically the structure that Amazon is looking for in an interview (though, some interviewers are better/worse than others) - start with the super inefficient solution, solve it pretty quickly - point out performance problems or edge cases that would need to be solved for a larger scale solution - go implement those optimizations
- kevincox 3y agoYup, when I was interviewing for Google I was expecting basically the same. I would like you to work though the problem and come up with something simple, bonus points if you noted places that could be buggy, slow or anything else. Then we would look at it and discuss what could be improved and if we had time maybe even make those improvements.
- kfrane 3y agoOne more that I've heard just recently: "If your code is just juggling with pointers/references, it is likely that it isn't doing much useful. It is only when it starts dealing with actual values that it is starting to do something useful."
- mrkeen 3y agoCounter-point to 5: Complex algorithms over simple data can have big performance payoffs, remove obstacles, and even simplify things. For instance, binary search over a sorted array (as opposed to a BinaryTree object): • simplifies merging (it's just concat & sort) • no pointers, which makes serialisation easier, but also... • bypasses the need for serialisation • an array can be on disk, or in memory, or both (via mmap) • the data can be bigger than your ram • allows for 'cold starts': just point your program at the file/mapping and tell it to run, no 'loading into ram' step. • it's also cache-oblivious Another example is huffman coding. If you studied it at uni, you probably saw it as a Tree-based algorithm with the associated O(n logn) time complexity. I was unaware that there was an in-place, array-based method of constructing a Huffman tree in linear time. Of course 99% of the time, I'm doing back-end microservices and just using standard collection data structures. But if I ever had a 'big data' task at work, I would strongly prefer to be able to do it on a single machine with a big disk locally rather than buy into whatever the current flavour of MapReduce is.
- rapsin4 3y agoDon't forget, you, the dev is 99% of the time the most expensive resource. Maintainability and first to market are usually way more important.
- wredue 3y ago>dev is the most expensive resource This is not true. Ask Facebook, who have rewritten things multiple times explicitly because this is not true, but someone assumed it was >maintain ability and first to market are usually more important Maintainability and first to market are not trade offs for performance in most cases, no matter how much you want to propagate this ridiculous propaganda.
- arp242 3y agoBut the question is, would Facebook still be around if they didn't "just ship this turd lol"? I don't really have any insight in Facebook engineering over the years and it's a "what if" type of question that's essentially unanswerable, but the answer to that being "no" is very plausible. And Facebook really does have unique(-ish) scalability problems, and I bet rewrites would have been inevitable even with the best possible engineering, because who can write an application to deal with a billion users (2012, currently 3 billion) right from the start? When Facebook launched in 2004 this was pretty much unheard of, and even in today it remains pretty rare (much less 2012).
- m3kw9 3y agoNo need to argue details, don’t over engineer your software, you all know who you are
- spacedcowboy 3y agoReminds me of the two rules for optimisation: 1. Don't. 2. (for experts only) Don't, yet.
- mikhailfranco 3y agoCorrect, beautiful, fast - in that order “Make it work, then make it beautiful, then if you really, really have to, make it fast. 90% of the time, if you make it beautiful, it will already be fast. So really, just make it beautiful!” - Joe Armstrong
- teo_zero 3y agoWhile I appreciate the humor in it, it may make you feel excused for writing inefficient code.
- rogierhofboer 3y agoI am missing a very important one: Don't communicate by sharing memory, share memory by communicating. https://www.youtube.com/watch?v=PAAkCSZUG1c&t=168s https://www.youtube.com/watch?v=PAAkCSZUG1c&t=168s And lot's of others here: https://go-proverbs.github.io/ https://go-proverbs.github.io/
- dang 3y agoRelated: Rob Pike's Rules of Programming (1989) - https://news.ycombinator.com/item?id=24135189 https://news.ycombinator.com/item?id=24135189 - Aug 2020 (323 comments) Rob Pike's 5 Rules of Programming - https://news.ycombinator.com/item?id=15776124 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 https://news.ycombinator.com/item?id=15265356 - Sept 2017 (112 comments) Rob Pike's Rules of Programming - https://news.ycombinator.com/item?id=7994102 https://news.ycombinator.com/item?id=7994102 - July 2014 (96 comments)
- layer8 3y 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. As a corollary, types are important. If everything is a string or a hash table, then things won’t be so self-evident.
- parasense 3y agoI could really care less what Rob Pike things about programming rules, coming from the person who things capitalising is a great way to export things, ignoring that capitalised characters are mostly just a Latin thing, and so the whole concept of his toy language is just that... forever a silly toy language.
- 38 3y agoits a shame that you would toss away an entire language because of a small gripe. I agree that the case thing is annoying, but Go has many strengths and is broadly useful in a variety of situations. when I started C++ was the "defacto" language, even taught in schools. for many years I avoided programming and I didn't know why. once Go came along it all clicked. I avoided programming because languages like C++ are awful. I could give reasons but people mostly know what they are. Go is great because its mostly simple, and the dev team is not afraid to "say no", even aggressively, if a feature is not strongly useful. plus the tooling is better than most languages one might come across.
- timacles 3y agoAh yea docker and kubernetes. The silly little playthings of the tech world
- kazinator 3y agoRule 0: you often can predict where the program is going to spend a lot of its time; don't use rule 1 as an excuse to be completely CS-ignorant. Likewise, don't use rule 3 as an excuse to use completely lame algorithms; "not fancy" doesn't mean Bubblesort. Unlike Pike in 1989, you have libraries.
- zubairq 3y agoGreat rules, need to read them every 6 months to embed them in my neural circuitry!
- eftychis 3y agoAre these quotes the reason we end up with bloated rarely optimized or respectful for memory, CPU, or other resources software systems nowadays? https://www.techradar.com/news/move-over-chrome-macos-monterey-is-the-new-ram-eating-monster-in-town https://www.techradar.com/news/move-over-chrome-macos-monter... https://www.tomsguide.com/news/google-chrome-reportedly-destroys-mac-performance-heres-how-to-fix-it https://www.tomsguide.com/news/google-chrome-reportedly-dest... A great majority using these quotes act like no engineering design work is allowed whatsoever. I have seen that mentality permeate everything even hitting concurrency decisions for obvious things. (E.g. We need to respond to HTTP requests while doing stuff in the background, and accessing IO and run multiple server state syncing but let us have purely synchronous, single threaded code and we will figure it all out later. That went well.) And for some reason there is a subgroup that thinks security architecture is "optimizations." It depends on the product but when you have https://news.ycombinator.com/item?id=38029479 https://news.ycombinator.com/item?id=38029479 or https://news.ycombinator.com/item?id=38076636 https://news.ycombinator.com/item?id=38076636 it is not over-engineering: it is management and business forcing poor product.