views:

1322

answers:

10
+5  Q: 

Recursion vs loops

I'm facing a problem where both recursion and using a loop seem like natural solutions. Is there a convention or "preferred method" for cases like this? (Obviously it is not quite as simple as below)

Recursion

Item Search(string desired, Scope scope) {
    foreach(Item item in scope.items)
        if(item.name == desired)
            return item;

    return scope.Parent ? Search(desired, scope.Parent) : null;
}

Loop

Item Search(string desired, Scope scope) {
    for(Scope cur = scope; cur != null; cur = cur.Parent)
        foreach(Item item in cur.items)
            if(item.name == desired)
                return item;

    return null;
}
+5  A: 

If you are using a functional language (doesn't appear to be so), go with recursion. If not, the loop will probably be better understood by anyone else working on the project. Of course, some tasks (like recursively searching a directory) are better suited to recursion than others.

Also, if the code cannot be optimized for tail end recursion, the loop is safer.

Ed Swangren
+1  A: 

Use the loop. It's easier to read and understand (reading code is always a lot harder than writing it), and is generally a lot faster.

Emil H
+3  A: 

I would say the recursion version is better understandable, but only with comments:

Item Search(string desired, Scope scope) {
    // search local items
    foreach(Item item in scope.items)
        if(item.name == desired)
            return item;

    // also search parent
    return scope.Parent ? Search(desired, scope.Parent) : null;
}

It is far easier to explain this version. Try to write a nice comment on the loop version and you will see.

ypnos
If you need the comments for that version but not for the loop, than I would argue that is a sign that the loop should be preferred in this case.
Ed Swangren
No, I personally think the loop needs even more comments. The comparison of readability is just much easier if you take comments into account. For the average-lazy-dontwanttothinkaboutit fellow programmer, both versions are not "self explanatory" enough.
ypnos
+9  A: 

I favor recursive solutions when:

  • The implementation of the recursion is much simpler than the iterative solution
  • I can be reasonably assured that the depth of the recursion will not cause a stack overflow (assuming we're talking about a language that implements recursion this way)

Condition 1 doesn't seem to be the case here. The iterative solution is about the same level of complexity, so I'd stick with the iterative route.

John Feminella
+4  A: 

Recursion is used to express an algorithm that is naturally recursive in a form that is more easily understandable. A "naturally recursive" algorithm is one where the answer is built from the answers to smaller sub-problems which are in turn built from the answers to yet smaller sub-problems, etc. For example, computing a factorial.

In a programming language that is not functional, an iterative approach is nearly always faster and more efficient than a recursive approach, so the reason to use recursion is clarity, not speed. If a recursive implementation ends up being less clear than an iterative implementation, then by all means avoid it.

In this particular case, I would judge the iterative implementation to be clearer.

Tyler McHenry
+2  A: 

I find the recursion more natural, but you may be forced to use the loop if your compiler doesn't do tail call optimization and your tree/list is too deep for the stack size.

Svante
+10  A: 

If performance matters, then benchmark both and choose on a rational basis. If not, then choose based on complexity, with concern for possible stack overflow.

There is a guideline from the classic book The Elements of Programming Style (by Kernighan and Plauger) that algorithm should follow data structure. That is, recursive structures are often processed more clearly with recursive algorithms.

RBerteig
A: 

If your code is compiled it will likely make little difference. Do some testing and see how much memory is used and how fast it runs.

Jay
+3  A: 

It is provable that all tail-recursive algorithms can be unrolled into a loop, and vice versa. Generally speaking, a recursive implementation of a recursive algorithm is clearer to follow for the programmer than the loop implementation, and is also easier to debug. Also generally speaking, the real-world performance of the loop implementation will be faster, as a branch/jump in a loop is typically faster to execute than pushing and popping a stack frame.

Personally speaking, for tail-recursive algorithms I prefer sticking with the recursive implementation in all but the most-performance-intensive situations.

Not Sure
A: 

If the system you're working on has a small stack (embedded systems), the recursion depth would be limited, so choosing the loop-based algorithm would be desired.

switchmode