我们可以使用getchar_unlocked通过操作类似的字符来快速读取stdin中的整数:
int scan_d()
{
int ip = getchar_unlocked(), ret = 0, flag = 1;
for(; ip < '0' || ip > '9'; ip = getchar_unlocked())
{
if(ip == '-')
{
flag = -1;
ip = getchar_unlocked();
break;
}
}
for(; ip >= '0'&& ip <= '9'; ip = getchar_unlocked())
ret = ret * 10 + ip - '0';
return flag * ret;
}
有没有办法使用上面的方法快速读取stdin中的字符串? gets比cin / scanf快,但同时拥有空白的关键处理。我想过为字符串修改上面的代码但是遇到了空白问题。此外,似乎逐个读取字符串的每个字符都会更慢。
通过stdin,我的意思是用户输入字符串(无文件处理)
答案 0 :(得分:3)
有没有办法使用上面的方法快速读取stdin中的字符串?
当然可以。如果您更清楚地预期它如何行动,我们甚至可以提供代码。
gets比cin / scanf快,但同时拥有对空白的批判性处理。
cin
和scanf
也可以这样做:How to cin Space in c++?和How do you allow spaces to be entered using scanf?
我想过为字符串修改上面的代码但是遇到了空白问题。
有什么问题? https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem
此外,似乎逐个读取字符串的每个字符都会变慢。
比块读取慢?当然。但是,一次读取一个字符实际上是判断字符串结尾的唯一方法。您可以阻止读入缓冲区并旋转它以查找字符串的结尾,这称为缓冲。但是stdin
已经被缓冲了,所以再次缓冲它会使更慢更快。读取空格分隔字符串的方法不会比一次使用getchar_unlocked
一个字符更快。
答案 1 :(得分:2)
不确定我的基准测试是否正确..这是我第一次真正测试速度..
无论如何,这里是:
#include <cstdio>
#include<iostream>
#include <sstream>
#include <chrono>
std::chrono::time_point<std::chrono::steady_clock> hClock()
{
return std::chrono::steady_clock::now();
}
std::uint32_t TimeDuration(std::chrono::time_point<std::chrono::steady_clock> Time)
{
return std::chrono::duration_cast<std::chrono::nanoseconds>(hClock() - Time).count();
}
void Benchmark(const char* Name, std::string &str, void(*func)(std::string &str))
{
auto time = hClock();
for (int i = 0; i < 100; ++i)
{
func(str);
str.clear();
}
std::cout<<Name<<" took: "<<TimeDuration(time) / 100<<" nano-seconds.\n";
}
void unlocked_bench(std::string &str)
{
char c = '0';
while((c = getchar_unlocked()) && (c != -1 && c != '\n' && c != '\r'))
{
str += c;
}
}
void getchar_bench(std::string &str)
{
char c = '0';
while((c = getchar()) && (c != -1 && c != '\n' && c != '\r'))
{
str += c;
}
}
void getline_bench(std::string &str)
{
std::cin.getline(&str[0], str.size());
}
void scanf_bench(std::string &str)
{
scanf("%[^\n]100s", &str[0]);
}
void fgets_bench(std::string &str)
{
fgets(&str[0], str.size(), stdin);
}
void cinread_bench(std::string &str)
{
std::cin.read(&str[0], str.size());
}
int main()
{
std::string str;
str.reserve(100);
Benchmark("getchar_unlocked", str, unlocked_bench);
Benchmark("getchar", str, getchar_bench);
Benchmark("getline", str, getline_bench);
Benchmark("scanf", str, scanf_bench);
Benchmark("fgets", str, fgets_bench);
Benchmark("cinread", str, cinread_bench);
return 0;
}
输入:
Hello There
Hello There
Hello There
Hello There
Hello There
Hello There
输出:
getchar_unlocked took: 436 nano-seconds.
getchar took: 330 nano-seconds.
getline took: 619 nano-seconds.
scanf took: 522 nano-seconds.
fgets took: 44 nano-seconds.
cinread took: 67 nano-seconds.
答案 2 :(得分:0)
由于人类比计算机慢,因此没有快速的方法来从用户输入您的程序。
如果用户以每分钟1个字母的速率打字,您的程序将等待1分钟以获得下一个字符。期。不能读得更快。
如果您的程序每秒可以从用户读取1个字符,并且我的程序需要1毫秒才能读取一个字符,则两个程序最终将等待60,000毫秒以便下一个用户的字符。我的程序更快吗?是。这有什么不同吗?没有。你驾驶的红色信号比我快吗?
根据我的经验,关于用户输入的所有优化都已关闭。不要打扰。 It wastes your time and annoys the pig.
如果您的程序需要30秒才能执行操作,则仍需要等待30秒才能让用户输入下一个字符。
专注于坚固性:
如果必须,阻止从用户读取或使用getline
读取字符串。