lundi 27 mars 2017

Why is std::cout so time consuming?

I have made a program to compute the permutations of an 8 character string "sharjeel".

#include <iostream>
#include <time.h>

char string[] = "sharjeel";
int len = 8;
int count = 0;

void swap(char& a, char& b){
    char t = a;
    a = b;
    b = t;
}
void permute(int pos) {
    if(pos==len-1){
        std::cout << ++count << "\t" << string << std::endl;
        return;
    }
    else {
        for (int i = pos; i < len;i++)
        {
            swap(string[i], string[pos]);
            permute(pos + 1);
            swap(string[i], string[pos]);
        }
    }
}

int main(){
    clock_t start = clock();
    permute(0);
    std::cout << "Permutations: " << count << std::endl;
    std::cout << "Time taken: " << (double)(clock() - start) / (double)CLOCKS_PER_SEC << std::endl;
    return 1;
}

If I print each permutation along it takes about 9.8 seconds for the execution to complete.

40314   lshaerej
40315   lshareej
40316   lshareje
40317   lshareej
40318   lshareje
40319   lsharjee
40320   lsharjee
Permutations: 40320
Time taken: 9.815

Now if I replace the line:

std::cout << ++count << "\t" << string << std::endl;

with this:

++count;

and then recompile, the output is:

Permutations: 40320
Time taken: 0.001

Running again:

Permutations: 40320
Time taken: 0.002

Compiled using g++ with -O3

Why is std::cout so relatively time consuming? Is there a way to print that is faster?

EDIT: Made a C# version of the program

/*
 * Permutations
 * in c#
 * much faster than the c++ version 
 */

using System;
using System.Diagnostics;

namespace Permutation_C
{
    class MainClass
    {
        private static uint len;
        private static char[] input;
        private static int count = 0;

        public static void Main (string[] args)
        {
            Console.Write ("Enter a string to permute: ");
            input = Console.ReadLine ().ToCharArray();
            len = Convert.ToUInt32(input.Length);
            Stopwatch clock = Stopwatch.StartNew();
            permute (0u);
            Console.WriteLine("Time Taken: {0} seconds", clock.ElapsedMilliseconds/1000.0);
        }

        static void permute(uint pos)
        {

            if (pos == len - 1u) {
                Console.WriteLine ("{0}.\t{1}",++count, new string(input));
                return;
            } else {
                for (uint i = pos; i < len; i++) {
                    swap (Convert.ToInt32(i),Convert.ToInt32(pos));
                    permute (pos + 1);
                    swap (Convert.ToInt32(i),Convert.ToInt32(pos));
                }
            }

        }
        static void swap(int a, int b) {
            char t = input[a];
            input[a] = input[b];
            input[b] = t;
        }
    }
}

Output:

40313.  lshaerje
40314.  lshaerej
40315.  lshareej
40316.  lshareje
40317.  lshareej
40318.  lshareje
40319.  lsharjee
40320.  lsharjee
Time Taken: 4.628 seconds
Press any key to continue . . .

Aucun commentaire:

Enregistrer un commentaire