私はあなたのコードだけでなく、以下の簡単な調整も行いました。微調整は、二倍の速さ以上のものです:ここでは
auto start = std::chrono::high_resolution_clock::now();
//original version
vector<bool> k;
vector<long long int> c;
for (int i=2;i<40000000;i++)
{
k.push_back(true);
c.push_back(i);
}
for (int i=0;i<sqrt(40000000)+1;i++)
{
if (k[i]==true)
{
for (int j=i+c[i];j<40000000;j=j+c[i])
{
k[j]=false;
}
}
}
vector <long long int> arr;
for (int i=0;i<40000000-2;i++)
{
if (k[i]==true)
{
arr.push_back(c[i]);
}
}
cout << arr.size() << endl ;
auto end1 = std::chrono::high_resolution_clock::now();
std::cout << "Elapsed = " <<
std::chrono::duration_cast<std::chrono::milliseconds>(end1 - start).count() <<
std::endl;
}
{
auto begin = std::chrono::high_resolution_clock::now();
//new version
const long limit{40000000};
vector<bool> k(limit-1,true);
//k[0] is the number 0
k[0]=false; k[1]=false;
auto sq = sqrt(limit) + 1;
//start at the number 2
for (int i=2;i<sq;i++)
{
if (k[i]==true)
{
for (int j=i+i;j<limit;j+=i)
{
k[j]=false;
}
}
}
vector <long long int> arr;
for (int i=0;i<limit-2;i++)
{
if (k[i]==true)
{
arr.push_back(i);
}
}
cout << arr.size() << endl ;
auto stop = std::chrono::high_resolution_clock::now();
std::cout << "Elapsed = " <<
std::chrono::duration_cast<std::chrono::milliseconds>(stop - begin).count() <<
std::endl;
}
デバッグモードで(ミリ秒単位で経過時間)の出力は、されています
2433654
Elapsed = 5787
2433654
Elapsed = 2432
の両方が同じ結果を持っている、第二には、はるかに高速です。ここで
は、(より少ないコードを必要とする)いくつかの素晴らしいC++の機能を使用して別のバージョンであり、そしてそれは、上述した第2のバージョンよりも約11%高速である:あなたの元のバージョンでは、あなたの3人にpush_back
こと
auto begin = std::chrono::high_resolution_clock::now();
const long limit{40000000};
vector<int> k(limit-1,0);
//fill with sequence of integers
std::iota(k.begin(),k.end(),0);
//k[0] is the number 0
//integers reset to 0 are not prime
k[0]=0; k[1]=0;
auto sq = sqrt(limit) + 1;
//start at the number 2
for (int i=2;i<sq;i++)
{
if (k[i])
{
for (int j=i+i;j<limit;j+=i)
{
k[j]=0;
}
}
}
auto results = std::remove(k.begin(),k.end(),0);
cout << results - k.begin() << endl ;
auto stop = std::chrono::high_resolution_clock::now();
std::cout << "Elapsed = " <<
std::chrono::duration_cast<std::chrono::milliseconds>(stop - begin).count() <<
std::endl;
}
注意現代の慣用句のこの使用は、vector
で動作しているときには、まったくpush_back
を使用することはありません。
この例では、vector
はint
です。これで、終了時に素数の実際の一覧が得られます。
出力:
2433654
Elapsed = 2160
これら上記のすべてのデバッグモード番号があります。リリースモードで
、あなたが実際の素数が終了しているものを気にしない場合は最高のは、boolsのベクターを用いて数値を使用して、上記第二と第三の技術を組み合わせたものです:
2433654
Elapsed = 1098
2433654
Elapsed bool remove= 410
2433654
Elapsed = 779
リリースモードでは、オリジナルのコードは5歳のノートパソコンで約1秒しかかかりませんので、デバッグモードで動作している可能性があります。
あなたの仕事は遅いです。 – YoTengoUnLCD
@YoTengoUnLCDあなたにいくつかの改善が提案されますか? – Nikhil
[成長の経験談、** please!***](http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth)セグメント化されたふるいに素早く切り替えるために、これはキャッシュの局所性を改善することになっています。あなたはベクトル 'c'を全く必要とせず、カウンタを維持するだけです。常に 'i = 2'から始まります。オッズのみの作業に切り替えると、for i = 3; ...; i + = 2 'となる。 'p = 2i + start_value' [または何か](http://ideone.com/fapob)のオッズ・パック・アレイを使用してください。 –