为什么getchar_unlocked()比替代品更快?

时间:2016-05-25 10:46:15

标签: c++ getchar

我知道这段代码是如何工作的,但我找不到为什么这段代码比其他i / o方法更快?

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;
}

2 个答案:

答案 0 :(得分:1)

scanf("%d\n", &x)必须解析格式字符串并在读取之前和之后锁定流。

std::cin >> x也可能会锁定,并且可能需要与stdin同步,并且可能需要经历一些抽象层。

通过上述方法,您只需要进行一种类型的输入解析(因此无需解析格式字符串并根据该解析确定要执行的操作),最重要的是,您不会锁定流。

POSIX要求锁定流,glibc使用递归互斥锁来防止多个线程(即使在单线程环境中)同时访问stdin FILE(这会破坏它)。 这些互斥锁非常昂贵(read_int应该比scanf("%d",&x)快几倍(fivish?)。

关于你的实施,除了解决幻数问题, 您可能也应该检测getchar_unlocked中的失败并通过单独的通道报告这些失败 - 例如,通过传入的指针返回解析的整数并使用返回状态进行错误报告。

如果您想要线程安全,您仍然可以使用getchar_unlocked获得与getchar相比的加速,但您必须在开头和结尾flockfile(stdin);funlock(stdin); (分别)你的read_int函数。

答案 1 :(得分:1)

线程之间的锁定很昂贵。这是一个非锁定IO调用。

https://discuss.codechef.com/questions/2667/getchar_unlocked