为什么使用所有数字来测试素数比仅使用素数更快

Why is using all numbers to test for a prime number faster than using prime numbers only

本文关键字:数字 为什么 测试      更新时间:2023-10-16

我做了这个程序来生成质数。我知道有很多公式可以将生成速度提高 100 倍,但这就是我所做的。

  1. 我试图将 i 与i下的所有数字分开。这是最简单的方法,但我认为它效率低下,因为除以 2 后,您不需要除以 4 等等。

  2. 我列出了一个小于i的质数列表,并i除以该列表的数字。我使用std::iterator浏览了列表,因为我看到它被用于所有 stackoverflow 答案和其他教程中。结果慢了很多。就像它花了 22 秒而不是 2 秒。

  3. 我尝试使用 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.";
}

因为它的用法vector<unsinged int>用于第三种方法。 特别是primes.push_back导致分配。尝试最初primes.reserve

我想说的主要问题是大多数情况下,一个数字可以被 2 整除,因此它不是素数。我想第一种方法对编译器和缓存更友好。但很难确定。此外,请尝试删除打印并测试所花费的时间。打印往往会减慢代码的速度,具体取决于使用情况。

一种确定所有素数的标准方法(有更有效的方法,但这个相当简单(。

  1. 创建布尔值的向量A,以指示数字是否为素数。但是在开始时将所有变量设置为 true - 除了A[0]=A[1]=false.

  2. i = 2 to x运行循环。如果A[i]是假的,则跳过它 -i不是素数。如果A[i]为真,则i为素数,并将所有A[i*k]设置为假1<k<x/i

这应该更有效的任何一种方法。

相关文章: