C# 优化素数生成代码?

C# 优化素数生成代码?,c#,optimization,primes,C#,Optimization,Primes,我已经编写了下面的代码来计算和输出素数 我得到的素数在控制台上输出并存储在文本文件中 它计算所有数字,直到指定一个为止 有什么建议可以让这段代码运行得更快更有效吗 static void Main(string[] args) { long i; long j; for (i = 3; i < 10000000; i += 2) { bool isPrime

我已经编写了下面的代码来计算和输出素数

我得到的素数在控制台上输出并存储在文本文件中

它计算所有数字,直到指定一个为止

有什么建议可以让这段代码运行得更快更有效吗

    static void Main(string[] args)
    {
        long i;
        long j;    

           for (i = 3; i < 10000000; i += 2)
           {
               bool isPrime = true;

               for (j = 2; j <= i / 2; j++)
               {
                   if (i % j == 0)
                   {
                       isPrime = false;
                       break;
                   }
               }

               if (isPrime)
               {
                   Console.WriteLine(i);

                   using (System.IO.StreamWriter StreamWriter = System.IO.File.AppendText(@"C:\Users\Marco\Documents\Visual Studio 2012\Projects\Prime Number Generator\Prime Number Generator\bin\Debug\Prime List.txt"))
                   {
                       StreamWriter.WriteLine(i);
                   }
               }
           }
    }
谢谢

您只需要在sqrti之前检查分区,而不需要检查i/2。正如@I4V在下面的评论中适当指出的,j*j 您可以在循环中使用以前找到的素数,即将它们存储在数组中并循环使用,因为您只需要检查素数的可除性


只有在优化了算法之后,才能开始优化代码。

1在sqrti结束循环,而不是在i/2结束循环。节省的时间值得计算平方根所需的时间


2不要忘记你生成的数字。将它们至少保存到最后一个数组中,然后尝试仅为已知的素数除以候选数。如果x%y==0,则y要么是素数,要么是素数P

您使用的算法称为试除法,它的时间复杂度为^2,如果您按照@sashkello和@giuliofranco的建议停在平方根上,则时间复杂度为^1.5。一个更好的算法是Eratosthenes筛,它是2000多年前发明的,其时间复杂度为logn,接近于logn。Eratosthenes的筛选从列出从2到最大期望素数n的所有数字开始,然后进入迭代阶段。在每一步中,确定尚未考虑的最小未交叉数,并划掉该数的所有倍数;重复此操作,直到没有未交叉的数字被忽略为止。所有未交叉的数都是素数

function primes(n)
    sieve := makeArray(2..n, True)
    for p from 2 to n step 1
        if sieve[p]
            output p
            for i from p*p to n step p
                sieve[i] := False
在primes函数中,sieve是数字列表,当sieve[p]为真时,未交叉的数字按升序考虑,并按所考虑的素数输出,而倍数的交叉由i上的循环完成;循环从p*p开始,因为所有较小的倍数都已被较小的素数划掉


如果你对素数编程感兴趣,我在我的博客上谦虚地推荐这个,它讨论了这个算法,给出了速度加倍的优化,提供了许多关于素数的其他算法,并给出了五种语言的实现。

只需生成所有的数,2…N,对于大N,这将生成所有素数,再加上一些误报。而且速度也很快。感谢以下几点,它确实缩短了程序查找X下所有素数的时间;如果不是,我将被隐式转换为double,平方根的计算速度可能会慢9倍,具体取决于体系结构参见@Kyle_the_hacker j*j@I4V:胡,我没看到这个。。。完全同意!它将比平方根条件快23倍。1筛子更好。2如果使用平方根,请使用double计算整数平方根一次。通过使用整数,可以避免在每次比较中进行整数到浮点的转换。您需要加倍,因为浮点开始在超过24位(约1600万)时丢失精度。因为你只做一次,平方根所花的时间并不重要。3如果你使用j*j=65536时已经溢出。我很失望你甚至没有在你的文章中提到,顺便说一句,这是一种参考算法,当涉及到轮因式分解等优化时。。。。它以ON/log/N的形式扩展,使用的内存比埃拉托什尼筛要少。@Kyle:这篇文章是介绍性的,而阿特金筛远远超出了介绍性。我确实在我的博客和其他地方实现了。注意这里涉及的渐进复杂性;尽管理论上有优势,但在实践中编写一个Atkin筛子或一个车轮筛子来击败Eratosthenes筛子要比看起来困难得多。我很高兴你觉得这篇文章很有趣,希望你喜欢。
function primes(n)
    sieve := makeArray(2..n, True)
    for p from 2 to n step 1
        if sieve[p]
            output p
            for i from p*p to n step p
                sieve[i] := False