我有一个函数,该函数应该将所有可被3和5整除的自然数相加。我不想满足于最明显的解决方案,而是试图提出比单一个for循环性能更好的东西。带有if语句。
我想出了下面的函数。起初只有一个参数limit
,但是后来我想尝试将计算分配给多个线程,因此我引入了第二个默认参数lowerLimit
。如果我运行并基准测试以下代码并将限制设置为99999999999999(lowerLimit,保留默认值),则该程序大约需要3.5秒。 但是,当我将类型从int更改为unsigned时,代码花费了很多时间来运行,因此我决定停止它,而不是等待输出。差异来自哪里?
TLDR:当LowerLimit的类型从int更改为unsigned时,以下代码为什么要花更多时间运行?
unsigned long sumNaturalNumbersDivisibleBy3And5UpToNumber(unsigned long limit, int lowerLimit = 0)
{
unsigned long sum = 0;
for (auto threes = lowerLimit + 3; threes <= limit; threes += 3)
{
sum += threes;
}
for (auto fives = lowerLimit + 5; fives <= limit; fives += 5)
{
sum += fives;
}
for (auto fifteens = lowerLimit + 15; fifteens <= limit; fifteens += 15)
{
sum -= fifteens;
}
return sum;
}
更新:正如PaulMcKenzie所建议的,将值分配给三,五和十五时可能存在溢出错误。我仍然不确定为什么会导致性能差距。
如果您的带有int lowerLimit
的版本实际上完成了,那是因为它溢出了,然后发生的是未定义的行为(对于有符号整数)。它也可以在2^31-1
到-2^31
之间环绕并永远继续循环-或做一些完全不同的事情(查找“ 鼻恶魔
我有一个函数,该函数应该将所有可被3和5整除的自然数相加。我不想满足于最明显的解决方案,而是试图提出比单一个for循环性能更好的东西。带有if语句。