Home  >  Article  >  Backend Development  >  Is C IOStreams Always Slower Than printf/scanf?

Is C IOStreams Always Slower Than printf/scanf?

Barbara Streisand
Barbara StreisandOriginal
2024-11-06 15:55:02150browse

Is C   IOStreams Always Slower Than printf/scanf?

Strategies to Enhance IOStream Performance

Most C programmers prefer the printf/scanf functions when coding in C , citing their superior interface. However, IOStreams often face performance concerns.

Buffering Optimization

Increasing the buffer size enhances performance by reducing HDD hits and system calls. This can be achieved by accessing the underlying streambuf and modifying its buffer:

char Buffer[N];

std::ifstream file("file.txt");

file.rdbuf()->pubsetbuf(Buffer, N);

Locale Handling

Locales can introduce performance overhead due to complex operations like character conversion and filtering. Consider using the default C locale, designed for uniformity and minimal conversions.

Synchronization

Synchronizing with stdio does not appear to improve performance. However, it's possible to access a global setting using std::ios_base::sync_with_stdio.

Measurements and Results

Performance results vary significantly depending on the implementation and platform. Some users have reported faster C IOStreams, while others have experienced slower performance.

Benchmarking Code

For those interested in running their own benchmarks, here's a sample code:

template <typename Func>
double benchmark(Func f, size_t iterations)
{
  f();

  timeval a, b;
  gettimeofday(&a, 0);
  for (; iterations--;)
  {
    f();
  }
  gettimeofday(&b, 0);
  return (b.tv_sec * (unsigned int)1e6 + b.tv_usec) -
         (a.tv_sec * (unsigned int)1e6 + a.tv_usec);
}

struct CRead
{
  CRead(char const* filename): _filename(filename) {}

  void operator()() {
    FILE* file = fopen(_filename, "r");

    int count = 0;
    while (fscanf(file,"%s", _buffer) == 1) { ++count; }

    fclose(file);
  }

  char const* _filename;
  char _buffer[1024];
};

struct CppRead
{
  CppRead(char const* filename): _filename(filename), _buffer() {}

  enum { BufferSize = 16184 };

  void operator()() {
    std::ifstream file(_filename, std::ifstream::in);

    file.rdbuf()->pubsetbuf(_buffer, BufferSize);

    int count = 0;
    std::string s;
    while (file >> s) { ++count; }
  }

  char const* _filename;
  char _buffer[BufferSize];
};

int main(int argc, char* argv[])
{
  size_t iterations = 1;
  if (argc > 1) { iterations = atoi(argv[1]); }

  char const* oldLocale = setlocale(LC_ALL,"C");
  if (strcmp(oldLocale, "C") != 0) {
    std::cout << "Replaced old locale '" << oldLocale << "' by 'C'\n";
  }

  char const* filename = "largefile.txt";

  CRead cread(filename);
  CppRead cppread(filename);

  bool oldSyncSetting = std::ios_base::sync_with_stdio(false);

  double ctime = benchmark(cread, iterations);
  double cpptime = benchmark(cppread, iterations);

  std::ios_base::sync_with_stdio(oldSyncSetting);

  std::cout << "C  : " << ctime << "\n"
               "C++: " << cpptime << "\n";

  return 0;
}

The above is the detailed content of Is C IOStreams Always Slower Than printf/scanf?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn