【发布时间】:2015-09-14 22:46:32
【问题描述】:
我目前有两种方法可以检查一个数字是否为素数,另一种方法可以计算两者都需要的时间。
IsPrime1:
bool IsPrime1(int i)
{
if (i == 2 || i == 3 || i == 5 || i == 7) return true;
return i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0;
}
IsPrime2:
bool IsPrime2(int i)
{
if (i == 2 || i == 3 || i == 5 || i == 7) return true;
if (i % 2 == 0) return false;
if (i % 3 == 0) return false;
if (i % 5 == 0) return false;
return i % 7 != 0;
}
CheckForTicks:
string CheckForTicks(int ticks)
{
var sw1 = Stopwatch.StartNew();
for (var g = 0; g < ticks; g++)
{
var b = IsPrime1(g);
}
sw1.Stop();
var sw2 = Stopwatch.StartNew();
for (var g = 0; g < ticks; g++)
{
var b = IsPrime2(g);
}
sw2.Stop();
return $"{ticks} ticks: IsPrime1: {sw1.ElapsedMilliseconds} ms / IsPrime2: {sw2.ElapsedMilliseconds} ms";
//equal to the following:
//return string.Format("{0} ticks: IsPrime1: {1} ms / IsPrime2: {2} ms", ticks, sw1.ElapsedMilliseconds, sw2.ElapsedMilliseconds);
}
结果:
| CheckForTicks | IsPrime1 (in ms) | IsPrime2 (in ms) |
|---------------|------------------|------------------|
| 100000 | 3 | 4 |
| 500000 | 18 | 21 |
| 1000000 | 37 | 45 |
| 5000000 | 221 | 242 |
| 10000000 | 402 | 499 |
| 50000000 | 2212 | 2320 |
| 100000000 | 4377 | 4676 |
| 500000000 | 22125 | 23786 |
我想知道的是,为什么IsPrime2 甚至比IsPrime1 慢一点。
从我的角度来看,IsPrime2 应该比IsPrime1 快得多,因为它只需要在第一个可能的return 和IsPrime1 检查所有可能性之前检查一次。
有什么我不知道的,或者这与.NET有关吗?
如果有人能向我解释造成这种情况的原因,我将不胜感激。
提前致谢!
PS:我正在使用Visual Studio 2015 RC 和.NET 4.6 并在Debug 模式下运行它。
【问题讨论】:
-
由于
&&的短路评估,它们完全相同。 -
你为什么还要检查
i % 9?i % 3... 涵盖了这一点 -
IsPrime1 检查所有可能性 不,它没有。在第一次失败后完成。
-
@OliverCharlesworth 给出了正确答案。但是像 11、13、...这样的素数呢?
-
这样的细微差别在误差范围内。如果你没有做适当的基准测试,这个差距会更大。
标签: c# performance if-statement primes