0

I want to achieve the following function:

string a;
cin>>a;

But cin is very slow. I want faster alternatives. One suggested thing was:

char temp[101]; string a;
scanf("%100s", temp);
a=temp;

But, to use that I must know maximum size of string, which i don't know.

What should I use?

Meet Taraviya
  • 869
  • 1
  • 8
  • 27
  • 3
    Are you piping input into your program or is the user entering it in? If the user is entering the data then You would never notice the time it takes for `cin` to run. – NathanOliver Jan 09 '16 at 04:22
  • 4
    Have you tried the usual improvements (e.g., toggling `sync_with_stdio`) yet? It's worth giving that a try before recreating `operator>>`. – chris Jan 09 '16 at 04:23
  • You should use your compiler optimization flags. – Trevor Hickey Jan 09 '16 at 04:39
  • 6
    What makes you think `cin` into a `std::string` is slow? What are you comparing it to? Where do you think the overhead might be? – Chris Beck Jan 09 '16 at 04:41
  • Related: [Read a big file by lines in C++](http://stackoverflow.com/q/32006765/86967) – Brent Bradburn Jan 09 '16 at 05:34
  • A related question about getting input in C++. It provides good benchmarks: [Why is reading lines from stdin much slower in C++ than Python?](http://stackoverflow.com/questions/9371238/why-is-reading-lines-from-stdin-much-slower-in-c-than-python) – hargasinski Jan 09 '16 at 06:11

2 Answers2

3

I tested the performances of fscanf and ifstream in reading the words from a file. While fscanf performs a little better than ifstream, I don't think it warrants a change of strategy. I am assuming that the relative performances of scanf and cin will be very similar.

My test platform: Linux, g++ 4.8.4.

File contents when run wc on it:

>> wc socc.in
321 1212 7912 socc.in

Relative performances:

Time taken: 0.894997 (using ifstream)
Time taken: 0.724011 (using fscanf)

Program used:

#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

#include <ctime>

void test1(std::string const& filename)
{
   std::ifstream infile(filename);
   if ( !infile )
   {
      return;
   }

   // Extract the words from the file using an ifstream.
   std::string a;
   while ( infile >> a );
}

void test2(std::string const& filename)
{
   FILE* infile = fopen(filename.c_str(), "r");
   if ( infile == NULL )
   {
      return;
   }

   // Extract the words from the file using an ifstream.
   // I know that my file does not have any word longer
   // than 999 characters.
   char word[1000];
   while ( fscanf(infile, "%s", word) == 1 );
   fclose(infile);
}

void repeat(void (*fun)(std::string const&),
            int count,
            std::string const& filename)
{
   for ( int i = 0; i < count; ++i )
   {
      fun(filename);
   }
}

void timeFunction(void (*fun)(std::string const&),
                  int count,
                  std::string const& filename)
{
   clock_t start = std::clock();
   repeat(fun, count, filename);
   clock_t end = std::clock();
   double secs = 1.0*(end-start)/CLOCKS_PER_SEC;
   std::cout << "Time taken: " << secs << std::endl;
}

int main(int argc, char** argv)
{
   int count = std::atoi(argv[1]);
   char* filename = argv[2];

   timeFunction(test1, count, filename);
   timeFunction(test2, count, filename);
}

Program execution and output:

>> ./socc 10000 socc.in
Time taken: 0.894997
Time taken: 0.724011
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    Nice work. I have run your benchmark and got the opposite result (1.1 s and 1.6 s). My input was a 48 MiB file with 100000 lines each containing between 0 and 999 (uniformly random) random characters (ASCII between `' '` and `'~'`) and I have run your program with 10 repetitions. I have compiled with `g++ -std=c++14 -DNDEBUG -O3`. Did you try a larger input. It seems to me that your results are dominated by the overhead for opening and closing the file. – 5gon12eder Jan 09 '16 at 05:44
  • @5gon12eder, after I increased the file size to 7.6 MiB and added the -O3 flag to the build line, I still see `fscanf` performing better than `ifstream` in my test environment. – R Sahu Jan 09 '16 at 05:52
  • Oh, btw: GCC 5.3.0 on x86_64 GNU/Linux 4.3.3-2. – 5gon12eder Jan 09 '16 at 05:52
  • g++ must have improved the performance of the C++ IO library between 4.8.4 and 5.3.0. – R Sahu Jan 09 '16 at 05:54
  • 2
    So, I think we can conclude what you say in the first paragraph: It probably doesn't warrant a change of strategy. Other factors dominate. – 5gon12eder Jan 09 '16 at 05:55
0

Still scanf() works!!

Various methods like gets() or even getch() can be looped to receive a string.

Sibidharan
  • 2,717
  • 2
  • 26
  • 54