Search code examples
c++getchar

Why is getchar_unlocked() faster than alternatives?


I know how this code works but i could not find why this code faster than other i/o methords???

int read_int() {
  char c = getchar_unlocked();
  while(c<'0' || c>'9') c = getchar_unlocked();
  int ret = 0;
  while(c>='0' && c<='9') {
    ret = 10 * ret + c - 48;
    c = getchar_unlocked();
  }
  return ret;
}

Solution

  • scanf("%d\n", &x) has to parse the format string and lock the stream before and after the reading.

    std::cin >> x might do locking too, and it might have to sync with stdin, and it might need to go through some abstraction layers.

    With the above, you only do one type of input parsing (so no need to parse a format string and decide what to do based on that) and most importantly, you don't lock the stream.

    Locking streams is mandated by POSIX, and glibc uses recursive mutexes to prevent multiple threads (even in a single-threaded environment) from accessing the stdin FILE simultaneously (which would corrupt it). These mutexes are quite expensive (your read_int should be several (fivish?) times faster than scanf("%d",&x)).


    Regarding your implementation, apart from fixing the magic number issue, you should probably detect failures in getchar_unlocked too and report those failures through a separate channel -- e.g., by returning the parsed integer through a passed-in pointer and using the return status for error reporting.

    If you want thread safety, you can still use getchar_unlocked to get a speedup compared to getchar, but you have to flockfile(stdin); and funlock(stdin); at the beginning and end (respectively) of your read_int function.