【问题标题】:Loop not faster despite looping through half as many iterations?尽管循环了一半的迭代,但循环速度不快?
【发布时间】:2018-09-01 15:44:02
【问题描述】:

我写了一个搜索素数的程序:

#include <iostream>
#include <fstream>
#include <chrono>

typedef std::chrono::high_resolution_clock Clock;
using namespace std;

int main() {
    int p;
    int x = 1;
    int b;
    int a[1000000];
    bool n = false;
    a[0] = 2;
    a[1] = 3;

    auto t1 = Clock::now();

    ofstream outfile;
    outfile.open("p.txt");

    for (p = 3; p < 7500000; p = p + 2)
    {
        for (b = 0; b <= x && n == 0; b++)
        {
            if (p % a[b / 2] == 0)
            {
                n = true;
            }
        }
        if (n == false)
        {
            cout << p << endl;
            outfile << p << endl;
            x++;
            a[x] = p;
        }
        else
        {
            n = false;
        }
    }

    auto t2 = Clock::now();
    std::cout
        << std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count()
        << " nanoseconds" << std::endl;
    outfile.close();
}

最初对于循环增量我有p++,但我将其更改为p=p+2,因为所有素数本质上都是奇数,不需要检查偶数。问题是当我对此进行基准测试时,新旧代码之间的速度没有差异。那么,如果检查所有数字与检查一半没有什么不同,那么这个过程中的瓶颈是什么?有没有更好的方法来解决这个问题?

【问题讨论】:

  • 这并没有解决问题,而是养成在创建对象时初始化对象的习惯,而不是稍后更新它们。特别是,将ofstream outfile; outfile.open("p.txt"); 替换为ofstream outfile("p.txt");。而且你不需要outfile.close();——析构函数会这样做。
  • 你的基准测试怎么样?
  • 请修正缩进。读到这里,我感觉就像坐过山车。
  • 另外,愚蠢的问题,你正在编译优化是吗?
  • 一个是你在循环中包含文件写入,在最好的情况下,写入文件可能会有很大差异,具体取决于 PC 上的其他进程在做什么,结合优化编译器你可能会得到不同的结果。

标签: c++ loops primes


【解决方案1】:

你的外循环跳过了一半的数字。但是您的内部循环会测试每个数字两次。所以你放弃了所有的收获。

如果您没有看到您的内部循环执行所有操作两次,请考虑 a[b/2]b 为 1 时与在 b 为 0 时相同。

【讨论】:

  • 这并不能解释为什么 not 跳过一半的数字不会加倍时间。
  • 注意,会解决这个问题。谢谢。
  • 它实际上解释了为什么它需要更多而不是两倍的时间。跳过偶数是一个小收获。两次处理实际的艰苦工作可能会花费更多。你回答了他问的问题。我解释了为什么他的代码比它应该的慢得多。 ;)
【解决方案2】:

就是这一行:

for(b=0; b<=x && n==0; b++)

一旦n=true; 执行,b 循环就会因为&amp;&amp; n==0 条件而退出。这发生在第一个测试中:每个偶数都可以被 2 整除,即a[0]。所以对于偶数(如果你使用p++而不是p=p+2,你包括在内)内部循环非常快,比典型的奇数快得多。这就解释了为什么将它们包括在内几乎没有什么区别。

【讨论】:

  • 是的,你想想就明白了,哈哈。谢谢
猜你喜欢
  • 2016-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-09
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
  • 2020-05-18
相关资源
最近更新 更多