为什么 getchar_unlocked() 比替代方法更快?
Why is getchar_unlocked() faster than alternatives?
我知道这段代码是如何工作的,但我找不到为什么这段代码比其他 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;
}
scanf("%d\n", &x)
读取前后都要解析格式串和锁流
std::cin >> x
也可能会进行锁定,并且可能必须与 stdin
同步,并且可能需要经过一些抽象层。
有了上面的内容,你只做一种类型的输入解析(所以不需要解析格式字符串并根据它决定做什么)而且最重要的是,你没有锁定流。
POSIX 强制锁定流,glibc 使用递归互斥锁来防止多个线程(即使在单线程环境中)同时访问标准输入 FILE
(这会破坏它)。
这些互斥量非常昂贵(您的 read_int
应该比 scanf("%d",&x)
快几倍(fivish?))。
关于您的实施,除了解决幻数问题外,
您可能也应该检测 getchar_unlocked
中的故障并通过单独的渠道报告这些故障——例如,通过传入的指针 return 分析解析的整数并使用 return 状态错误报告。
如果你想要线程安全,你仍然可以使用getchar_unlocked
来获得比getchar
更快的速度,但是你必须在开始时使用flockfile(stdin);
和funlock(stdin);
并(分别)结束 read_int
函数。
线程之间的锁定是昂贵的。这是一个非锁定 IO 调用。
https://discuss.codechef.com/questions/2667/getchar_unlocked
我知道这段代码是如何工作的,但我找不到为什么这段代码比其他 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;
}
scanf("%d\n", &x)
读取前后都要解析格式串和锁流
std::cin >> x
也可能会进行锁定,并且可能必须与 stdin
同步,并且可能需要经过一些抽象层。
有了上面的内容,你只做一种类型的输入解析(所以不需要解析格式字符串并根据它决定做什么)而且最重要的是,你没有锁定流。
POSIX 强制锁定流,glibc 使用递归互斥锁来防止多个线程(即使在单线程环境中)同时访问标准输入 FILE
(这会破坏它)。
这些互斥量非常昂贵(您的 read_int
应该比 scanf("%d",&x)
快几倍(fivish?))。
关于您的实施,除了解决幻数问题外,
您可能也应该检测 getchar_unlocked
中的故障并通过单独的渠道报告这些故障——例如,通过传入的指针 return 分析解析的整数并使用 return 状态错误报告。
如果你想要线程安全,你仍然可以使用getchar_unlocked
来获得比getchar
更快的速度,但是你必须在开始时使用flockfile(stdin);
和funlock(stdin);
并(分别)结束 read_int
函数。
线程之间的锁定是昂贵的。这是一个非锁定 IO 调用。
https://discuss.codechef.com/questions/2667/getchar_unlocked