1

In the book Accelerated C++ Programming, on page 205, there are the two following implementation of find

 template <class In, class X> In find(In begin, In end, const X& x)

I am interested in knowing what is any difference in terms of performance (whether it's actually the same after the compilation?) of the following two implementations.

non-recursive

template <class In, class X> In find(In begin, In end, const X& x)
{
    while (begin != end && *begin != x)
        ++begin;
    return begin;
}

recursive

template <class In, class X> In find(In begin, In end, const X& x)
{
    if (begin == end || *begin == x)
        return begin;
    begin++;
    return find(begin, end, x);
}

By using Compiler Explorer suggested by Kerrek I got the following

non-recursive https://godbolt.org/g/waKUF2

recursive https://godbolt.org/g/VKNnYZ

It seems to be exactly the same after the compilation? (If I use the tool correctly.. Sorry, I am very new to C++)

  • 1
    Why don't you just try both and *tell us* what you find? – Kerrek SB Jan 08 '17 at 15:31
  • 1
    Tail recursion can lead to nice, clean solutions, but you'd better hope your compiler optimizes that into a loop instead of recursing (which pretty much all compilers will do if passed the necessary optimization flags, but probably won't if optimizations are turned off (like in a debug build)). Otherwise you could get a stack overflow if you search a long list. – Cornstalks Jan 08 '17 at 15:33
  • [Example](https://godbolt.org/g/Ql4X3d) – Kerrek SB Jan 08 '17 at 15:33
  • @Kerrek I am new to c++ from python background, I am not yet familiar with with cprofile or the compiling process, but you are right I should certainly try it myself. Just saw your Example thanks for telling me this!! – Yuhao Tiger Huang Jan 08 '17 at 15:34
  • 2
    @YuhaoTigerHuang: I always find it curious that people want to discuss something that they don't actually seem to be very interested in. If you did care about how C++ compilers generate code, you would a) have some interest in machine code (so you can even phrase your interest coherently), and b) find out how to inspect the compiler output (e.g. `gcc -S`, or profile). Otherwise, if you have no particular interest in those things, then just use whichever code you like better until you actually encounter a problem that would force you to develop an interest. – Kerrek SB Jan 08 '17 at 15:37
  • One small nit: you should be using `++begin` in your recursive `find` if you want these comparisons to be more equal. – Cornstalks Jan 08 '17 at 15:40
  • The online compiler is very good at optimising tail calls; it has both inlined `find_rec` and transformed the recursion into a loop. – molbdnilo Jan 08 '17 at 17:41

2 Answers2

1

Recursive functions will add additionally elements on the stack. This can potentially cause stackoverflow errors depending on the state of the stack before starting recursion and the number of times you recurse.

Each function call pushes data onto the stack which includes the return address. This continues until the data is found. At this time, all of the functions will start to return the value that the last function returned until the we finally get back to the function that called the original find.

The exact amount of data stored for each function call depends on the calling convention and architecture. There is also overhead from pushing data on the stack which can make the algorithm slower, but that depends on the algorithm.

This is strictly for recursion that is not tail call optimized.

nopjmp
  • 42
  • 2
0

For the most part recursion is slower, and takes up more of the stack as well. The main advantage of recursion is that for problems like tree traversal it make the algorithm a little easier or more "elegant".

Check out some of the comparisons: Recursion vs Iteration

Shashi Kundan
  • 343
  • 1
  • 11
  • 1
    Your answer is only true if the compiler isn't optimizing. Pretty much all compilers can optimize tail recursion (though might require you to enable such optimization). In the optimized case, there should be no difference here. – Cornstalks Jan 08 '17 at 15:40