Recurrent merge sort (without recursion) For educational purpose I implement recurrent merge sort without recursion. The algorithm idea seems absolutely clear but my implementation appears to be really slow:


5 seconds to sort 10,000 values;
6 minutes to sort 100,000 values;
it was not able to finish 10,000,000 in several hours (while lib sort() function does it in aboit 6 seconds);


I guess, the problem is in my understanding of how C++ works. Maybe, I must not copy vectors to funtion and use pointers insted?

#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
#include &lt;ctime&gt;

void check_sort(std::vector&lt;int&gt; array); //test sorted arrays
void merge_sort(std::vector&lt;int&gt; array); //recurrent merge sort
std::vector&lt;int&gt; merge(std::vector&lt;int&gt; array, unsigned int b, unsigned int c, unsigned int e);

int main()
{
    unsigned int size;
    std::cout &lt;&lt; "Please enter the size of your array:" &lt;&lt; std::endl;
    std::cin &gt;&gt; size;

    std::vector&lt;int&gt; initial_array(size); //array of random elements

    //prefill arrays
    srand(time(0));
    for (unsigned int i; i &lt; initial_array.size(); ++i) {
        initial_array[i] = rand();
    }

    merge_sort(initial_array);

 /* DEBUGGER
    std::cout &lt;&lt; "initial array" &lt;&lt; std::endl;
    for (unsigned int i = 0; i &lt; initial_array.size(); ++i) {
        std::cout &lt;&lt; initial_array[i] &lt;&lt; " ";
    }
    std::cout &lt;&lt; std::endl;
*/

    return 0;
}

void merge_sort(std::vector&lt;int&gt; array)
{
    std::cout &lt;&lt; "merge sort" &lt;&lt; std::endl;
    check_sort(array);
    /* DEBUGGER
    std::cout &lt;&lt; "initial array" &lt;&lt; std::endl;
    for (unsigned int i = 0; i &lt; array.size(); ++i) {
        std::cout &lt;&lt; array[i] &lt;&lt; " ";
    } */

    float start_time =  clock();
    unsigned int n = array.size();
    for (unsigned int s = 1; s &lt; n; s *= 2)
    {
        for (unsigned int b = 0; b &lt; n; b += s*2)
        {
            unsigned int c = std::min(b + s - 1, n - 1);
            unsigned int e = std::min(c + s, n - 1);
            array = merge(array, b, c, e);
        }
    }
    float end_time = clock() - start_time;
    /* DEBUGGER
    for (unsigned int i = 0; i &lt; array.size(); ++i) {
        std::cout &lt;&lt; array[i] &lt;&lt; " ";
    } */
    check_sort(array);
    std::cout &lt;&lt; "time: " &lt;&lt; end_time/1000 &lt;&lt; std::endl;
}

std::vector&lt;int&gt; merge(std::vector&lt;int&gt; array, unsigned int b, unsigned int c, unsigned int e) {
    std::vector&lt;int&gt; C(array);
    unsigned int i1 = b; unsigned int i2 = c + 1; //start point in each piece
    unsigned int n1 = c; unsigned int n2 = e; //end point of each piece
    for (unsigned i = b; i &lt;= e; ++i)
    {
        if (i1 &gt; n1) //
        {
            C[i] = array[i2];
            ++i2;
        }
        else if (i2 &gt; n2)
        {
            C[i] = array[i1];
            ++i1;
        }
        else if (array[i1] &lt;= array[i2]) {
            C[i] = array[i1];
            ++i1;
        }
        else
        {
            C[i] = array[i2];
            ++i2;
        }
    }
    return C;
}


void check_sort(std::vector&lt;int&gt; array)
{
    for (unsigned int i = 0; i &lt; (array.size() - 1); ++i)
    {
        if (array[i] &gt; (array[i + 1]))
        {
            std::cout &lt;&lt; "unsorted" &lt;&lt; std::endl;
            return;
        }
    }
    std::cout &lt;&lt; "sorted" &lt;&lt; std::endl;
}
I see a number of things that may help you improve your code.

Rearrange the code to reduce the need for declarations

A function declaration is only needed by the compiler if it hasn't already encountered the function itself.  With that said, if the functions in the file are in the order check_sort, merge, merge_sort and then main, no separate function declarations would be needed.

Separate I/O from logic

The check_sort routine is not bad as it is, but I'd advocate separating the I/O from the logic.  That is, rename check_sort to is_sorted and have it return a bool value of true only if the vector is sorted.  Leave the printing to the calling function instead.

Use const where practical

The check_sort function does not alter the passed vector, so that should be passed as const &amp;:

void check_sort(const std::vector&lt;int&gt; &amp;array)


Consider using references

While this code works, there is still some room for improvement.  The easy thing to do to speed up the code is to simply use references like this:

std::vector&lt;int&gt; merge(std::vector&lt;int&gt; &amp;array, unsigned int b, unsigned int c, unsigned int e) {


By having it &amp;array instead of array you tell the compiler that it may use the passed object directly rather than making a copy.  This single change makes the code run about twice as fast on my machine.

Omit return 0

When a C++ program reaches the end of main the compiler will automatically generate code to return 0, so it is not necessary to put return 0; explicitly at the end of main.

There's more, but that's all I have time for at the moment.