【发布时间】:2020-03-20 01:12:40
【问题描述】:
我制作了这个程序来生成素数。我知道有很多公式可以将它们的生成速度提高 100 倍,但这就是我所做的。
我尝试将 i 与
i下的所有数字相除。那是最简单的方法,但我认为它效率低下,因为除以 2 后,您不需要除以 4 等等。我制作了一个小于
i的素数列表,并将i除以该列表的数字。我使用std::iterator浏览了列表,因为我看到它被用于所有stackoverflow 答案和其他教程。结果速度慢了很多。就像它花了 22 秒而不是 2 秒。- 我尝试使用 int 遍历列表,但又花了 2 秒。
接下来,我用 1 000 000 来查看方法 1 和 3 之间的区别。令我惊讶的是,方法 1 更快。这是为什么?不应该只使用素数来测试比使用所有数字更快吗?
#include <iostream>
#include <vector>
#include <chrono>
int main()
{
std::cout << "how high do you want to generate prime numbers? ";
int x;
// typed 1 000 000
std::cin >> x;
auto starttime = std::chrono::high_resolution_clock::now();
std::vector<unsigned int> primes;
bool isPrime;
for (int i = 2; i <= x; ++i) {
isPrime = true;
// takes 293 seconds
//for (int div{ 2 }; div < i; ++div) {
// if ((i % div) == 0) {
// takes really really long
//for (std::vector<unsigned int>::iterator div = primes.begin(); div != primes.end(); ++div) {
//if ((i % *div) == 0) {
// takes 356 seconds
for (int iter = 0; iter < primes.size(); ++iter) {
if ((i % primes[iter]) == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes.push_back(i);
std::cout << i << " ";
}
}
std::cout << "generating prime numbers up to " << x << " took " <<
round(static_cast<std::chrono::duration<double>>((std::chrono::high_resolution_clock::now() - starttime)).count())
<< " seconds.";
}
【问题讨论】:
-
我猜标题与问题正文相反。
-
哎呀抱歉,正在修复它
-
我敢打赌(我目前无法检查)是使用向量在内存访问上花费的时间比在整数模上保存的时间要多。请注意,您只需要检查除数直到 i 的平方根,包括在内。这样可以节省很多时间。
-
性能时序技术调查:stackoverflow.com/a/5694432/576911
-
确保您测试优化版本,不调试版本。