Stories
Slash Boxes
Comments

SoylentNews is people

posted by hubie on Monday June 10, @04:23PM   Printer-friendly
from the new-years-resolution dept.

Thomas A. Limoncelli writes in Make Two Trips:

During an interview on The Late Show with Stephen Colbert, comedian Larry David explained that his New Year's Resolution was "make two trips" (episode 857, January 8, 2020).

For example, when carrying groceries into the house, it is tempting to carry everything at once, but then you drop the cantaloupe, and now you have to clean up that mess. While it seemed like one trip would have been faster, if you include the time it takes to clean up the mess, it would have been faster to simply make two trips.

[...] This "make two trips" strategy isn't an earth-shattering breakthrough. It won't cure cancer, end world hunger, or fix the climate crisis. However, I have adopted this philosophy, and it has had many benefits.

The immediate benefit is that I am now more likely to have a free hand to open my house door. Pulling keys out of my pocket no longer involves smashing a grocery bag between my chest and the house.

The larger benefit has come from adopting this philosophy in both coding and operations.

The other day, I was adding a feature to some old code. The code reported results of an earlier calculation with various formatting options that could be enabled or disabled.

The code was quite complex because certain options affected the format in ways that had downstream implications for other options. The code was able to satisfy all the various options and controls in one pass over the data, printing a report along the way.

[...] I struggled in earnest to add my new feature to this ever-growing complicated loop.

Then I remembered Larry's advice: Make two trips.

The code would be significantly simpler if it made two passes over the data. One pass would collect data, count things that needed to be counted, sum subtotals, and so on. The second pass would take all this information and output the report, and would be much easier because it had all the information it needed from the start. No Schrödinger's cat.

[...] It was a classic complexity vs. memory engineering decision: Suffer from complexity or suffer from potential memory exhaustion.

... continue reading the whole article at ACM Queue.


Original Submission

This discussion was created by hubie (1068) for logged-in users only. Log in and try again!
Display Options Threshold/Breakthrough Mark All as Read Mark All as Unread
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
(1)
  • (Score: 3, Interesting) by khallow on Monday June 10, @05:01PM (3 children)

    by khallow (3766) Subscriber Badge on Monday June 10, @05:01PM (#1360048) Journal
    Consider what happens if you get interrupted during the transportation of groceries. There might be, depending where you live, opportunity for animal or human theft of your groceries. Or your groceries get a bit warm. There's some chance for minor risks from the second trip, but you're not spilling groceries all over the place. Tradeoffs favor breaking the task into two trips. But that's not always the case.

    There's the mantra I recall from my old accounting boss - hold paper once. When you take multiple passes through large batches of important documents (like processing sales reports for an active retail or restaurant outlet), you make multiple opportunities both to forget important things and to leave your desk in an indeterminate mess when you're interrupted halfway through (say your night staff gets interrupted by a fire alarm or locks themselves out of the office and you come in to a thick layer of paper over everything that needs sorting out). There's a place for single pass as well.

    With the shopping scenario, imagine if you had to do two passes every time you wanted to put something in the shopping cart. Get some hamburger, salt, buns, condiments, etc. then go back through that whole list to complete the getting of each item. What happens if you get interrupted in the middle of that? Touch food once.

    A computing example would be ACID technique in databases (atomicity and isolation in particular). A transaction is carried through to completion before starting another transaction that would conflict with that operation. You don't want your database dying with thousands of transactions in indeterminate state.

    There's cases for both breaking up and consolidating tasks. Often both should be done at the same time.
    • (Score: 5, Insightful) by Mykl on Monday June 10, @11:12PM (2 children)

      by Mykl (1112) on Monday June 10, @11:12PM (#1360092)

      In my experience, developers who come up with super-complex single-statement database updates are much more resistant to change requests than those who logically structure a sequence of steps as part of a multi-statement transaction.

      Just like your math teacher liked you to show your working rather than just spitting an answer out at the end, it can be incredibly useful to break a complex activity down into multiple steps. It can make the code easier to debug, maintain and enhance.

      • (Score: 5, Insightful) by krishnoid on Tuesday June 11, @12:07AM

        by krishnoid (1156) on Tuesday June 11, @12:07AM (#1360096)

        After it's broken down, you can then look at how easy it is to debug, maintain, enhance, and explain ... and after that, decide if what you get from compressing it back into a super-complex single-statement update is worth losing the original benefits.

        At the least, you can see if the performance of the maintainable version is ok, and you still have the option of optimizing performance-critical parts of it, while preserving most of the original benefits. And importantly, your successors won't curse your name every time they need to change something.

      • (Score: 2) by DannyB on Tuesday June 11, @03:42PM

        by DannyB (5839) Subscriber Badge on Tuesday June 11, @03:42PM (#1360182) Journal

        Strongly agree.

        There is nothing wrong with breaking a complex database query into multiple parts. Generate intermediate temporary table variables, etc. This also makes is tremendously easier to debug. You can look at what is in those intermediate table variable results to make sure they are correct for the subsequent steps.

        All those table variables disappear at the end of the transaction.

        And, this all happens in a database transaction. Either ALL of it happens, or NONE of it happens. So no worries about breaking a large complex operation into multiple steps.

        It is easier to read and comprehend -- especially for the next guy if well commented.

        Finally, breaking it down this way can sometimes greatly improve performance. You may have insights about the data or how to do this that the query optimizer does not. Maybe the gigantic query took a long time, but the four steps you broke it down into happen very fast. (I've actually had this happen before.) Let the query optimizer micro optimize things. But you have the big picture in your mind.

        --
        Since nobody defrags SSDs anymore, they are more (or less?) prone to failure of their seek mechanisms.
  • (Score: 5, Insightful) by Rosco P. Coltrane on Monday June 10, @05:38PM (2 children)

    by Rosco P. Coltrane (4757) on Monday June 10, @05:38PM (#1360053)

    It was a classic complexity vs. memory engineering decision

    Then computing became essentially free, universities started graduating engineers who code webpages in Javascript interfacing with remote servers in java with fifteen layers of terrible OO web-two-oh frameworks in-between, without a clue what's happening under the hood, and throwing more memory, more cpu and more bandwidth at the problem until it works roughly as fast as an Atari ST from the mid 80s.

    And now people rediscover basic optimization problems from yesteryear that real engineers could grapple with in first year at college, like it was anything new or Earth-shattering...

    • (Score: 4, Interesting) by looorg on Monday June 10, @06:55PM (1 child)

      by looorg (578) on Monday June 10, @06:55PM (#1360067)

      The code would be significantly simpler if it made two passes over the data. One pass would collect data, count things that needed to be counted, sum subtotals, and so on. The second pass would take all this information and output the report, and would be much easier because it had all the information it needed from the start. No Schrödinger's cat.

      Then computing became essentially free

      In some regard it's true. It became essentially free. Then people didn't have to care anymore. You could just pipe your data straight into your included lib and then it would compute and output. Zero optimization. But why bother since there are just so many resources. It feels somewhat odd and weird tho that the next generation of programmers, or whatever we should refer to them as, seems to try and reinvent the wheel all over again and then expect some kind of acknowledgement?

      In some regard I, clearly wrongly, lived with the idea that this is how you do things. Gather data, compute (with) data, display result. But I would assume that if you don't actually know what you are computing but just that "use this library" or whatever you have no idea what you are actually doing. So you basically start from scratch at every computation and then just loop that. After all things are so fast. How will you ever know. If you know your formulas and equations, for some topic more then others, you will find a lot of common computations that can be calculated and then reused in all the other equations where applicable and then then you just saved a bunch of computations. The question is perhaps if that is worth if from a thinking and system resources point of view. After all if you have basically infinite resources why bother saving and optimizing.

      • (Score: 4, Insightful) by JoeMerchant on Monday June 10, @08:44PM

        by JoeMerchant (3937) on Monday June 10, @08:44PM (#1360075)

        I realize we can descend into endless semantics arguments, but TFA reads to me like: separate the business logic from the user interface.

        It's a good philosophy, except when you really only have a small load of groceries that are trivially carried in one trip. In code, if your requirements aren't going to creep and grow, doing it all in one trip is both simpler and easier to maintain. If like our currently developing system, you have six loads of groceries to carry, expanding to eight in the foreseeable future, then the modular approach with well defined interfaces is the only sane way to approach things.

        In today's world, don't forget to secure those module interfaces while retaining the ability to expand the system through the secure interfaces in the future.

        Of course the typical codebase started as something trivially simple, easily implemented in a modified "Hello World" template, and grew incrementally over the years with various contributors each making "quick and easy" expansions to the functionality without knowing or caring how the base system worked, just testing (inadequately) to assure that they didn't mess up the previous functionality.

        --
        🌻🌻 [google.com]
  • (Score: 1, Interesting) by Anonymous Coward on Monday June 10, @06:14PM (3 children)

    by Anonymous Coward on Monday June 10, @06:14PM (#1360060)

    > (episode 857, January 8, 2020).

    Larry David is nearly 10 years older than me and he only figured this out ~5 years ago?

    The exact same thing occurred to me years earlier. One situation comes to mind, I was carrying things in from the car and added one more item to the top of the pile in my arms. While opening the screen/storm door to go inside, the pile dropped...and unfortunately that included a valuable glass keepsake that shattered.

    I remembered a saying which (afaik) I heard from my New England grandmother, "Haste makes waste." Touch wood, I haven't repeated it since, but I'm sure I'll mess up at some point as I get older.

    • (Score: 3, Informative) by mhajicek on Monday June 10, @08:32PM (1 child)

      by mhajicek (51) on Monday June 10, @08:32PM (#1360073)

      I think this is a clear example of "know your limits and don't try to exceed them."

      --
      The spacelike surfaces of time foliations can have a cusp at the surface of discontinuity. - P. Hajicek
      • (Score: 2) by vux984 on Monday June 10, @11:14PM

        by vux984 (5045) on Monday June 10, @11:14PM (#1360093)

        I thought it more of a 'measure twice cut once' type of thing.

        It's not exactly the same, but conceptually its the same wisdom: trying to take a shortcut to save time often ends up taking longer and/or costing more.

    • (Score: 5, Funny) by Gaaark on Monday June 10, @09:11PM

      by Gaaark (41) on Monday June 10, @09:11PM (#1360079) Journal

      I decided to drive to the grocery store: i took my car.

      After i got there, i remembered my wife's van could hold more groceries, so i thought, "Make two trips!"

      So i walked home and got my wife's van and drove it to the store!

      Damn, i'm smart! ;)

      --
      --- Please remind me if I haven't been civil to you: I'm channeling MDC. ---Gaaark 2.0 ---
  • (Score: 2) by cmdrklarg on Monday June 10, @06:29PM (2 children)

    by cmdrklarg (5048) Subscriber Badge on Monday June 10, @06:29PM (#1360063)

    Heh, my son would jokingly say that "trips are for the weak" as he was attempting to carry as much as possible. After he dropped too many items he learned to do otherwise.

    --
    The world is full of kings and queens who blind your eyes and steal your dreams.
    • (Score: 5, Funny) by driverless on Monday June 10, @08:23PM

      by driverless (4770) on Monday June 10, @08:23PM (#1360072)

      But then as you get older your just automatically make multiple trips for everything. For example you go out into the kitchen and then when you get there forget why you went, then go back into the lounge and realise you left your glasses somewhere... maybe it was the kitchen...

    • (Score: 3, Informative) by krishnoid on Tuesday June 11, @12:12AM

      by krishnoid (1156) on Tuesday June 11, @12:12AM (#1360098)

      Or use the wonders of modern technology [baggu.com]. These hold 50 pounds from the handles and fit in your back pocket. Still not for the weak, but the weak can set them down rather than dropping them. They frequently have good Black Friday/end of year clearance sales.

  • (Score: 4, Informative) by istartedi on Tuesday June 11, @12:07AM (4 children)

    by istartedi (123) on Tuesday June 11, @12:07AM (#1360097) Journal

    When I read the headline, I thought it would be less about algorithms and more about work habits. I've seen developers hit "global search and replace" when refactoring the code, and get bit by things like locals with the same name as a global. The result was hours of debugging caused by something they thought would save time. Even when global search turned out dozens of hits, I preferred to review each one. It took time and seemed mindless, but I immediately saw whether or not it was a function, local or global that we wanted to rename. It also served as a bit of code-review since it made you look at functions that you hadn't thought about for a while, potentially raising issue that needed to be addressed. It didn't impact productivity much either way I think. The occasional disaster was balanced by the slower changes; but I think my stress level was lower.

    In my hobby work, I've done a compiler as multiple passes when many people might have gone for one. I also find that to be a nice trade-off. The code is easier to understand that way. Since it's a hobby project it's possible that it would never scale; but I see that as somebody else's problem in the unlikely event that people are building an entire operating system with my language in the year 2100. Their hardware will have no trouble handling it, so they'll probably decide multiple passes are fine also.

    --
    Appended to the end of comments you post. Max: 120 chars.
    • (Score: 2) by krishnoid on Tuesday June 11, @12:16AM

      by krishnoid (1156) on Tuesday June 11, @12:16AM (#1360099)

      Then again, you could rework the compiler as persistent daemon(s) that implement a pipeline, which don't need to start/terminate a process for each compiled file. Still slower than a single pass, but other optimizations might avail themselves and maintenance is still easier.

    • (Score: 4, Interesting) by DannyB on Tuesday June 11, @03:55PM (2 children)

      by DannyB (5839) Subscriber Badge on Tuesday June 11, @03:55PM (#1360187) Journal

      I've seen developers hit "global search and replace" when refactoring the code, and get bit by things like locals with the same name as a global.

      In an IDE that does refactoring, Eclipse in my case, on a language that is "toolable" and supports refactoring, this should not be a problem.

      In my IDE when I select an identifier, and pick Refactor --> Rename, it renames this identifier globally throughout the entire project using the same understanding of the code as the compiler has. It is not a dumb "search and replace". Use of the same identifier in other scopes, not actually this same identifier, won't be renamed.

      Other uses of the same identifier name are clearly different according to the rules of the language. There is no ambiguity. You never look at an identifier (at least in Java) and wonder exactly what it is, where it is declared, etc. And if you don't know where it is declared, you hit an F-key or pick the command to take you to the declaration, and you will be taken directly to wherever this identifier is declared -- there can be no possible ambiguity or confusion about this according to the rules of the language.

      --
      Since nobody defrags SSDs anymore, they are more (or less?) prone to failure of their seek mechanisms.
      • (Score: 2) by istartedi on Tuesday June 11, @08:42PM (1 child)

        by istartedi (123) on Tuesday June 11, @08:42PM (#1360210) Journal

        It's cool that they've come that far with refactoring tools. I'm thinking of stuff I saw 15+ years ago. I don't know what tools they were using, just that it was C++ and they dug a hole for themselves. At least it didn't have the "Scunthorpe" problem--at least I don't think it did. That would be truly heinous. That's the problem where you decide to get "cunt" out of things. Let's say you change it to "baddy", and the truly stupid tools default to doing the replacement even inside of tokens so Scunthorpe become Sbaddythorpe. IIRC the problem was named because stories mentioning the town of Scunthorpe got blocked by language filters due to "cunt" being in it.

        --
        Appended to the end of comments you post. Max: 120 chars.
        • (Score: 2) by DannyB on Tuesday June 11, @10:08PM

          by DannyB (5839) Subscriber Badge on Tuesday June 11, @10:08PM (#1360216) Journal

          In 2004 I started using Eclipse. It had refactoring way back then. There's no magic. The IDE keeps a database which has a deep structural understanding of all your code. As you edit the code, this database and the object code are updated. The compiler is integrated with the editor that deeply. If you type something that breaks other code in the project, all those other files in the project almost instantly get red flags on them that they will no longer compile.

          The other part of this magic is that the Java language is "toolable". The rules are clear. There is no ambiguity. Tools can process code written in the language. In JavaScript or Python, you can't be sure what an identifier means. The environment is so dynamic that there might not even be a "declaration" of that identifier in a conventional sense. For example adding members to an object at runtime that weren't there at "edit" time. Now being this dynamic can be great for rapid prototyping of small to medium sized programs. However there is a reason why large enterprise programs are written in Java -- especially when they need to be long lived, maybe outliving the original programmer, and maintained by many people over time. The rules are rigid and clear. No wondering what magic is behind this identifier.

          Other forms of refactoring in Eclipse. Select these six lines of code in some big function and "yank" them out into a new small function. Eclipse will rewrite the code for you replacing the six lines with a call to the new function now having these six lines.

          And templates. All kinds of templates and you can write your own. As example, the FOR loop:

          for( int i = __; i __; i++ ) {
          }

          Now if you rename the "i", the other "i"'s on that line will simultaneously rename keystroke by keystroke as you type.

          You can create custom templates. If you had a custom template, say with a for loop with uses of "i" within the loop, they would also get renamed as you renamed the loop control variable "i".

          You only need to hit a few keystrokes to insert a template for some control structure of your choice, or other repetitively used block of code. The template is always inserted with correct indentation.

          I haven't even scratched the surface. These IDEs have a long learning curve. However you can begin using it productively almost immediately.

          --
          Since nobody defrags SSDs anymore, they are more (or less?) prone to failure of their seek mechanisms.
  • (Score: 2, Interesting) by Runaway1956 on Tuesday June 11, @01:49AM

    by Runaway1956 (2926) Subscriber Badge on Tuesday June 11, @01:49AM (#1360105) Journal

    I bought a cute little wagon for my wife. She doesn't have to carry groceries from the car. She unloads them from the luggage nets and bags in the back of the car, into the wagon. She pulls the wagon right into the kitchen. Then she puts groceries away. Unless, of course, someone else is at home, in which case, she orders that person(s) out to get the groceries. My wife loves that wagon, because she hates carrying groceries.

    Don't make two trips, figure out how to make one trip suffice.

    --
    ‘Never trust a man whose uncle was eaten by cannibals’
(1)