ビット配列を限界いっぱいまでC#プライムジェネレータ、

StackOverflow https://stackoverflow.com/questions/973891

  •  13-09-2019
  •  | 
  •  

質問

(C#の、素数発生器)

:友人と私は上のチャンスをうかがった相続人は、いくつかのコード
public List<int> GetListToTop(int top)
{            
    top++;
    List<int> result = new List<int>();
    BitArray primes = new BitArray(top / 2);
    int root = (int)Math.Sqrt(top);
    for (int i = 3, count = 3; i <= root; i += 2, count++)
    {
        int n = i - count;
        if (!primes[n])
            for (int j = n + i; j < top / 2; j += i)
            {
                primes[j] = true;
            }
    }
    if (top >= 2)
        result.Add(2);            
    for (int i = 0, count = 3; i < primes.Length; i++, count++)
    {
        if (!primes[i])
        {
            int n = i + count;
            result.Add(n);
        }
    }

    return result;
}

私の役立たずのAMDのx64 1800+(デュアルコア)で、34546.875msで10億以下のすべての素数のために。問題は、ビット配列で、よりを格納しているようです。 〜20億はbitarrayが店に望んでいるよりも多くのよりも多くのクランクしようとしています。その周りを取得する方法上の任意のアイデア?

役に立ちましたか?

解決

私は、ディスクへのアウト配列の「スワップ」の部分だろう。そのことで、私が意味する、あなたのビット配列は、ハーフ億ビットのチャンクに分割し、ディスク上に格納ます。

ザ・は、いずれかの時点でメモリ内の少数の塊を持っています。 C#の(または任意の他のオブジェクト指向言語)で、このチャンキングクラス内部の巨大な配列をカプセル化するために簡単なはずです。

あなたは遅く生成時間とそれを支払うだろうが、我々はより大きなアドレス空間と128ビットのコンパイラを取得するまで、私はその周りにどのような方法が表示されません。

他のヒント

またはpaxによって提案されたものと別のアプローチとして、.NET 4.0で新たにメモリマップファイルのクラスを利用すると、OSが任意の時点でメモリにする必要があるチャンク決定させます。

あなたは不必要にし、メモリ不足のページを交換するまで終わらないように(この一文が作るよりも、それは音トリッキー)しようとすると、局所性を高めるためのアルゴリズムを最適化したいと思うことが

注ます。

の最大サイズを大きくするために、複数のBitArraysを使用してください。数がある場合に大きなそれをビットシフトとビット33-64を格納するためのビット配列に結果を格納します。

BitArray second = new BitArray(int.MaxValue);
long num = 23958923589;
if (num > int.MaxValue)
{
    int shifted = (int)num >> 32;
    second[shifted] = true;
}

long request = 0902305023;
if (request > int.MaxValue)
{
    int shifted = (int)request >> 32;
    return second[shifted];
}
else return first[request];
BitArrayがSystem.Numerics.BigIntegerにサイズアップをサポートする場合は、

もちろん、それはいいだろう。
ディスクにスワップすることはあなたのコードが本当に遅くなります。
私は、64ビットのOSを持っている、と私のBitArrayは、32ビットに制限されます。

PS:あなたの素数の計算が奇妙に見える、鉱山は次のようになります:

for (int i = 2; i <= number; i++)
    if (primes[i])
        for (int scalar = i + i; scalar <= number; scalar += i)
        {
            primes[scalar] = false;
            yield return scalar;
        }

ふるいアルゴリズムは、より高性能になります。私はそれで4分未満のintの範囲のすべての32ビットの素数(合計約105万人)決定することができます。メモリ要件は少し400 MB以上(= 4バイト1つのint型)が存在することになるともちろん素数のリストを返すことは別物です。数字はファイルに出力した後、64ビットしかしながらもっと楽しく:)のためにDBにインポートされたforループを使用すると、プログラムはいくつかの修正を必要とし、おそらく複数のノードに分散実行を必要とするプライミング。また、以下のリンクを参照してください。

http://www.troubleshooters.com/codecorn/primenumbers/primenumbers.htm

http://en.wikipedia.org/wiki/Prime-counting_functionする

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top