• xmunk@sh.itjust.works
    link
    fedilink
    arrow-up
    7
    ·
    11 months ago

    When you can’t reasonably use a loop or when it’s not particularly important for performance and the recursive function is more readable.

    Honestly, in code the absolute most important quality is readability. Readability should always be prioritized until you find performance issues that matter in a specific block of code.

    • xxd@discuss.tchncs.de
      link
      fedilink
      English
      arrow-up
      4
      arrow-down
      1
      ·
      11 months ago

      On a side note: not caring about performance “until you find performance issues” is a huge problem with modern software imho. That’s the reason apps are so slow, updates take so long, everything uses so much space. I’d wish that performance would always be a point of consideration, not an afterthought once there are problems.

      • xmunk@sh.itjust.works
        link
        fedilink
        arrow-up
        5
        ·
        11 months ago

        I’d rather people err on the side of readability… senior devs should know the importance of readability but still lay decent groundwork towards performance… do things the right way when it can be simple.

        Junior developers should just focus on readable code. Chances are their code will be slow, indecipherable, and wrong - I’d rather they focused on fixing the indecipherablity, the wrongness, and then the speed.

        But, to sort of generally undermine my own point - no rule should be an absolute in software development - sometimes premature optimization is totally justified - you just need to use common sense.

        • xxd@discuss.tchncs.de
          link
          fedilink
          arrow-up
          2
          ·
          11 months ago

          I agree that junior devs should focus on readability, rather than focusing on everything and just getting it all wrong. but as you say, if you have more experience, performance should be a point of consideration.

          • CapeWearingAeroplane@sopuli.xyz
            link
            fedilink
            arrow-up
            2
            ·
            11 months ago

            I think people talking about premature optimisation are often talking about micro-optimisations. Those are almost always unnecessary until you’ve identified choke points. Optimising the overall architecture of the code base on the other hand, is in my opinion something that should be thought about before you even start coding. That’s where the major gains can often be done anyway.

      • Lysergid@lemmy.ml
        link
        fedilink
        arrow-up
        3
        ·
        edit-2
        11 months ago

        I don’t think loop vs recursion choice is what significantly impacts performance in most cases. Most of the software I saw, suffer performance because of wrong API design or overall architecture. If app needs to fetch 100 objects from API which can provide only one object at the time no optimization will save that app.

        App team - we need bulk API.

        API team - cannot because of capacity, budget, backward compatibility, DB, 3rd patry API, not a KPI

        Also it’s mostly QAs measuring performance and validating it with product guidelines which set by person who mostly detached from specific product and sometimes reality.

        • xxd@discuss.tchncs.de
          link
          fedilink
          arrow-up
          1
          ·
          11 months ago

          I think loops tend to be faster, but well done recursion might be just as fast. I just wanted to mention performance being a point of consideration when making these decisions. I 100% agree that poor (API) architecture is probably one of the biggest reasons for slow software. It’s just that every bit of poor performance adds up along the way, and then we end up having fast computers (that are orders of magnitude faster than anything 15 years ago) running bloated electron apps (that are sometimes even slower than their equivalent 15 years ago) and it’s just frustrating.

      • eluvatar@programming.dev
        link
        fedilink
        arrow-up
        0
        arrow-down
        1
        ·
        11 months ago

        Yeah but performance has way more to do with architecture than it does code readability. It doesn’t matter how well you write your code, if it’s an electron app it’s going to use more ram than a native app. So I totally agree, but at the scale that it’s a real problem it has more to do with architecture than the code in any given function.

        • bitcrafter@programming.dev
          link
          fedilink
          English
          arrow-up
          2
          ·
          11 months ago

          Yeah but performance has way more to do with architecture than it does code readability.

          Indeed, I am a bit notorious at work for speeding C++ code up by rewriting it in Python, and I have been able to do this not because my Python code is particularly fast but because the architecture of the C++ code was such a complicated and inefficient mess that it actually managed to be slower than Python.

  • swordsmanluke@programming.dev
    link
    fedilink
    arrow-up
    6
    ·
    11 months ago

    Generally, some algorithms are more easily expressed as recursive functions than iterative loops. …and vice versa. And realistically, that’s how you should choose ninety nine percent of the time.

    But if you want to get into the weeds… Prefer iteration unless you know one or more of the following:

    • Your maximum iteration depth is bounded and cannot overflow your machine’s stack depth.
    • Your algorithm can be implemented with tail-call recursion AND your language supports the same.
    • Your senior/team lead wants a recursive solution.

    Because in environments where none of the above are true, iterative solutions are usually more performant, safer, and better understood.

    • pinchcramp@lemmy.dbzer0.com
      link
      fedilink
      arrow-up
      2
      ·
      edit-2
      11 months ago

      Your algorithm can be implemented with tail-call recursion AND your language supports the same.

      Just to nitpick but the compiler/interpreter needs to support tail-call recursion, not just the language. For example, tail-call recursion is part of the language spec for JavaScript (ECMAScript 6), but only certain engines actually support it (https://compat-table.github.io/compat-table/es6/ Ctrl+F tail call).

  • vzq@lemmy.blahaj.zone
    link
    fedilink
    arrow-up
    6
    ·
    11 months ago

    Best for what?

    For performance you almost always want an iterative instead of recursive. But performance is not the only constraint.

    Some algorithms are innately recursive. Forcing them into an iterative paradigm usually makes them less readable.

    If you are compelled to make a recursive algorithm iterative, consider using an explicit stack. Then you can keep the structure and side step the issues related to call overhead and stack depth.

    • fiah@discuss.tchncs.de
      link
      fedilink
      arrow-up
      1
      ·
      11 months ago

      If you are compelled to make a recursive algorithm iterative, consider using an explicit stack.

      yep, did that once to solve a specific problem, worked fine and if I recall correctly I could do it without making a total mess of my code

  • jjagaimo@lemmy.ca
    link
    fedilink
    English
    arrow-up
    2
    ·
    11 months ago

    It depends on if the problem is recursive or iterative, and how much it needs to be optimized.

    For example, you may use a for loop for a simple find and replace scheme for characters in a string, where you check each character one by one until you find one which matches the target, and then substitute that.

    There are certainly recursive ways to do string replacement in strings which might be faster than an iterative search depending on implementation, but that’s more optimization than I might need 99.9999% of the time

    A recursive problem that’s difficult to solve iteratively is browsing all the files in a folder and it’s subfolders. Each folder may have several subfolders, which you then need to search, but then each of those folders can have subfolders. This problem can be solved fairly easily recursively but not as easily iteratively.

    That’s not to say it can’t be solved that way, but the implementation may be easier to write

    Recursive code, however, is more frequently prone to bugs which causes infinite recursion leading to crashes, as it is not a tool which is often used and requires several more fences to prevent issues. For example, in the folder example, if one were to encounter a shortcut to another folder and implement code to follow that shortcut as if it were a directory as well, then placing a shortcut to a folder within itself might cause the code to recurse infinitely without having a maximum recursion depth and or checking for previously seen folders.

    • atheken@programming.dev
      link
      fedilink
      arrow-up
      2
      ·
      11 months ago

      I generally find that writing code that requires a lot of “accounting” is very prone to mistakes that are easier to avoid with recursion. What I mean by this is stuff where you’re tracking multiple counters and sets on each iteration. It’s very easy to produce off by one errors in these types of algos.

      Recursion, once you get the hang of it, can make certain kinds of problems “trivial,” and with tail-call recursion being implemented in many languages, the related memory costs have also been somewhat mitigated.

      Loops are simpler for beginners to understand, but I don’t think recursion is all that hard to learn with a bit of practice, and can really clean up some otherwise very complicated code.

      My general opinion is that we are all beginners for a short part of our journey, but our aim shouldn’t be to make everything simple enough that beginners never need to advance their skills. We spend most of our careers as journeymen, and that’s the level of understanding we should be aiming for/expecting for most code. Recursion in that context is absolutely ok from a “readability/complexity” perspective.

    • Nommer@sh.itjust.works
      link
      fedilink
      arrow-up
      0
      ·
      11 months ago

      Could your folder tree problem also be solved with a whole loop instead? I’m very new but it seems like recursion is harder but possibly more optimized approach to loops or am I incorrect here?

      • mercator_rejection@programming.dev
        link
        fedilink
        arrow-up
        2
        ·
        11 months ago

        Any recursive algorithm can be made iterative and vise versa. It really depends on the algorithm if the function calls are a major factor in performance.

      • Faresh@lemmy.ml
        link
        fedilink
        English
        arrow-up
        2
        ·
        11 months ago

        Recursion is never more efficient than the best equivalent iterative solution. Recursion however allows you to solve some problems very easily and very neatly.

      • jjagaimo@lemmy.ca
        link
        fedilink
        English
        arrow-up
        2
        ·
        edit-2
        11 months ago

        I’m exaggerating a bit there. This problem is fairly easy to implement iteratively (e.g. keep a list of unbrowsed folders and keep adding to it), but that is not the case for all problems. Some will be easier to solve in one way, though fundamentally solvable either way

      • coloredgrayscale@programming.dev
        link
        fedilink
        arrow-up
        1
        ·
        11 months ago

        A naive iterative implementation would be by adding and removing the folders/files from a list.

        If tail call optimization works on the (recursive) example then that’s (kinda) the compiler turning a recursive function into a loop.

  • cvttsd2si@programming.dev
    link
    fedilink
    arrow-up
    1
    ·
    edit-2
    11 months ago

    When doing functional programming, you can’t really do loops (because of referential transparency, you can’t update iterators or indices). However, recursion still works.

  • apotheotic (she/her)@beehaw.org
    link
    fedilink
    English
    arrow-up
    1
    ·
    11 months ago

    Depends on the environment you’re working in. If you’re doing a lot of collaboration, it might be that you want to choose whichever of the two is more legible (almost always the loop, but perhaps the recursion). If you are in an environment where the most efficient approach is prioritised over readability, perhaps recursion would have a strong case in some circumstances.

    But I think, generally, you need to answer the underlying question, not “recursion or loop”. Can I improve code readability? Is this problem well suited to recursion? Am I just using recursion because it’s elegant? The correct approach will reveal itsself!

  • lysdexic@programming.dev
    link
    fedilink
    English
    arrow-up
    1
    arrow-down
    1
    ·
    11 months ago

    As a rule of thumb, I would say that recursion should never be used in place of a for loop.

    If you don’t know what you’re doing with a recursive function then you risk pushing stuff to your call stack proportionally to the number of items you want to iterate over.

    If your collection and/or the size of the stuff you’re pushing to the stack is large enough, your app will crash.

    If you know enough to avoid growing the call stack then you know enough to not rely on third parties to figure out if you need an iteration of recursion.