我正在编写代码,该代码从用户获取一个数字,然后以字母形式打印在字符串中。我想知道,在性能方面更好,有if语句,比如
if (n < 100) {
// code for 2-digit numbers
} else if (n < 1000) {
// code for 3-digit numbers
} // etc..
或将数字放入字符串并获取其长度,然后将其作为字符串处理。
代码是用C ++编写的。
答案 0 :(得分:1)
当然if-else
会更快。
要比较两个数字,你只需按位比较它们(有不同的方法可以做到这一点,但这是一个非常快的操作)。
要获得字符串的长度,您需要创建字符串,将数据放入其中并以某种方式计算长度(也可以采用不同的方式,最简单的方法是计算所有符号)。当然需要更多的时间。
在一个简单的例子中,你不会发现任何差异。人们常常对这些事情感到惊讶(没有冒犯)。如果代码将在0.003
秒内执行而不是0.001
秒,那么对您来说没有任何区别......只有在知道这个确切的位置是您的应用程序的瓶颈,当您确定时,您可以将性能提高相当多。
答案 1 :(得分:0)
在衡量之前,这确实是一个瓶颈,不要担心性能。
也就是说,以下内容应该更快(为了便于阅读,我们假设您使用的范围介于0到99999999之间):
if (n < 10000) {
// code for less or equal to 4 digits
if (n < 100)
{
//code for less or equal to 2 digits
if (n < 10)
return 1;
else
return 2;
}
else
{
//code for over 2 digits, but under or equal to 4
if (n>=1000)
return 4;
else
return 3;
}
} else {
//similar
} // etc..
基本上,它是二元搜索的变体。最糟糕的情况是,这将采用O(log(n))
而不是O(n)
- n
是最大位数。
答案 2 :(得分:0)
string
变体会变慢:
std::stringstream ss; // allocation, initialization ...
ss << 4711; // parsing, setting internal flags, ...
std::string str = ss.str(); // allocations, array copies ...
// cleaning up (compiler does it for you) ...
str.~string();
ss.~stringstream(); // destruction ...
...
表示发生了更多事情。
紧凑(适用于缓存)循环(适用于分支预测)可能是您想要的:
int num_digits (int value, int base=10) {
int num = 0;
while (value) {
value /= base;
++num;
}
return num;
}
int num_zeros (int value, int base=10) {
return num_decimal_digits(value, base) - 1;
}
根据具体情况,因为它是缓存和预测友好的,这可能比基于关系运算符的解决方案更快。
模板化变体使编译器能够为您的部门进行一些微优化:
template <int base=10>
int num_digits (int value) {
int num = 0;
while (value) {
value /= base;
++num;
}
return num;
}
答案 3 :(得分:0)
答案很好,但请考虑相关时间。
即使你能想到的最慢的方法,程序也可以在很短的一秒钟内完成,就像100微秒一样。
与你能想象到的最快的用户相比,谁可以在500毫秒内输入数字,谁能在另外500毫秒内读取输出,然后再做下一件事。
好吧,机器基本上没有1000毫秒的时间,并且在中间它必须疯狂地处理100微秒,因为毕竟我们不希望用户认为程序很慢; - )