Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何生成以下C++;程序更快?_C++_Performance - Fatal编程技术网

C++ 如何生成以下C++;程序更快?

C++ 如何生成以下C++;程序更快?,c++,performance,C++,Performance,与问题相关的链接- 问题如下-找出a和b之间的质数(包括a和b,如果它们是质数的话) 我使用了Eratosthenes筛来解决这个问题,但是我在两个测试用例中得到了超时 特别是对于一个有10000个数字的测试用例,我的C++程序在代码块中花费了大约10秒。我在下面插入代码片段- for(int i=2;i<=upperbound;i++) { prime[i-2]=i; } int sq=sqrt(upperbound); for(int i=0;prime[i]<=sq;i

与问题相关的链接-

问题如下-找出a和b之间的质数(包括a和b,如果它们是质数的话)

我使用了Eratosthenes筛来解决这个问题,但是我在两个测试用例中得到了超时

<>特别是对于一个有10000个数字的测试用例,我的C++程序在代码块中花费了大约10秒。我在下面插入代码片段-

for(int i=2;i<=upperbound;i++)
{
    prime[i-2]=i;
}
int sq=sqrt(upperbound);
for(int i=0;prime[i]<=sq;i++)
{
    if(prime[i]!=0)
    {
        int j=i+prime[i];
        for(;j<m;j+=prime[i])
        {
            prime[j]=0;
        }
    }
}

for(inti=2;i我在代码中看到的唯一时间吞咽器是使用
sqrt

您可以使用

但这只是一个小小的进步

您必须更改算法以获得更好的结果。 搜索素数是一个困难的问题,有很多最差的解决方案(例如,你可以使用…

你正在使用
sqrt
,这可能会很耗时,特别是当它找到双根时。你甚至不使用
sq

编辑:尝试将循环中的
上限
替换为
sq
。这会解决一些速度问题,但不会解决segfault,这可能是由于分配了太大的内存块造成的


筛子算法的问题是,它为所有数字分配完整的数组

寻找素数的另一种方法是用素数除以所有的数直到它们的平方根。该算法的一个简单优化是避免偶数。并且只将素数存储在一个结构中

int lastBound = 0; //avoids doing too many multiplications
vector<int> primes;

primes.push_back(2);

for (int i = 3; i <= upperbound; i+= 2) {
    bool prime = true;
    for(int j : primes) {
         if (j > lastBound && j * j > i) {
             lastBound = j;
             break;
         }

         if (i%j == 0) {
             prime = false;
             break;
         }
    }

    if (prime) {
        primes.push_back(i);
    }
}
int lastbund=0;//避免执行太多乘法
向量素数;
素数。推回(2);
对于(int i=3;i最后一次绑定&j*j>i){
lastbund=j;
打破
}
如果(i%j==0){
素数=假;
打破
}
}
if(prime){
素数。推回(i);
}
}
然后列表中有素数,可以将其转换为数组,比如,一个集合,或者其他什么


有些动态分配可能会导致一些延迟,但是对于大小为
n
向量
,只有O(log(n))分配。可能会有进一步的优化,但对于您的目的来说,这应该足够了。

您在数组中有效地存储了两次素数。
prime[i]==i+2
,因此您可以将
int j=i+prime[i];
替换为
int j=i+(i+2);

现在,如果您不再需要实际值,您可以只存储一位:
std::vector prime(上限,true);
。这将减少95%的内存需求(可能),这使得您的筛选适合CPU缓存


prime
的开头保存2位是个坏主意。在其他地方,一条
i-2
指令至少会占用一个整字节,并且会占用实际运行时间。

您正在计算
sqrt
(可能很昂贵)有两件事:你定义了
sq
,但似乎没有使用它;你使用了
m
,但没有定义它(在你包含的代码片段中)。此外,如果其中一个测试用例导致seg故障,则输出不能“完全正确”。您可能应该显示更多的代码和导致问题的测试用例。在我看来,这不像是一个Eratosthenes的筛子。看看这里的伪代码:您是在发布模式下构建的吗?您的编译器选项是什么?特别是优化选项。您尝试过评测吗?Sqrt会杀死它。您似乎没有使用value也返回了。如果您知道正在计算哪些平方根,您可以用一个查找表替换实现。@g24l
emplace\u back
只有在
向量
包含一个以
int
作为其非复制构造函数参数的类时才有用,这里它与
push\u back
?@ 1nFLKTD:对不起,太习惯于Qt,我的意思是<代码>(int j:Primes)< /代码>。使用<代码>预留()/代码>避免重新分配向量。我怀疑<代码> ListBoint 是悲观的。<代码>(j*j> i)中断;< /C> >已经非常有效。此外,我也考虑展开3。(这意味着在循环中做一个i+=4,然后重复代码,因此您可以检查5,7,11,13,17,19,23,…)通常的修复方法是替换
x0
,因此甚至不需要替换的前半部分。