![]() |
![]() |
![]() |
![]() |
01: // g++ -O2 nprime.cpp -o nprime_cpp 02: #include <iostream> 03: #include <vector> // 指摘により list &rarr vector に書き換える 04: 05: #define W 500 06: 07: using namespace std; 08: 09: 10: inline bool primep(vector<int>& plist, int i){ // 指摘により参照渡しにする 11: for( vector<int>::iterator iter = plist.begin();iter != plist.end(); iter++){ 12: int j = *iter; 13: if(j*j>i) return true; 14: if(i%j==0) return false; 15: } 16: } 17: 18: void nprime(int m){ 19: vector<int> plist; 20: plist.push_back(2); 21: plist.push_back(3); 22: for(int j =5, r=3; j <= m; j+=2, r++){ 23: if(primep(plist, j)) plist.push_back(j); 24: if(r==W){ 25: cout << j << " " << plist.size() << "\n"; 26: r = 0; 27: } 28: } 29: } 30: 31: int main(int ac, char** av){ 32: if(ac ==2){ 33: int m = atoi(av[1]); 34: if(m > 10000){ 35: cout << "#Limit, N of primes\n0 0\n"; 36: nprime(m); 37: return 0; 38: }else{ 39: cerr << "limit should be > 10000\n"; 40: } 41: }else{ 42: cerr << "Usage: nprime_cpp N\n"; 43: } 44: }
$ g++ -O2 nprime.cpp -o nprime_cpp $ time ./nprime_cpp 10000000 > nprime_cpp.dat real 0m8.365s user 0m8.245s sys 0m0.004s8.365 秒で終わりました。やはり早いです。
01: -- primitive couting prime numbers program 02: -- sacomp -O_fast nprime.sa -o nprime_sa 03: 04: class MAIN is 05: attr plist :LIST{INT}; 06: const w:INT := 500; 07: 08: private primep(i:INT):BOOL is 09: j:INT; 10: 11: loop 12: j :=self.plist.elt!; 13: if j * j > i then 14: return true; 15: end; 16: if i % j = 0 then 17: return false; 18: end; 19: end; 20: end; 21: 22: 23: nprime(maxi:INT) is 24: j,r:INT; 25: self.plist := #(|2,3|); 26: r := 3; 27: loop 28: j := 5.step!((maxi-3)/2, 2); 29: if self.primep(j) then 30: self.plist.append(j); 31: end; 32: if r = w then 33: #OUT + j + " " + self.plist.size + "\n"; 34: r := 0; 35: end; 36: r := r+1; 37: end; 38: end; 39: 40: main(av:ARRAY{STR}) is 41: if av.size = 2 then 42: m:INT := av[1].cursor.get_int; 43: if m <= 10000 then 44: #ERR + "limit should be > 10000\n"; 45: else 46: #OUT +"# limit, N of primes\n0 0\n"; 47: nprime(m); 48: end; 49: else 50: #ERR + "Usage: nprime N\n" 51: end; 52: end; 53: end;やっていることは C++ で書いたものと同じです。C++ のと Sather のを比べてみてください。
$sacomp -O_fast nprime.sa -o nprime_sa $time nprime_sa 10000000 > nrpime_sa.dat real 0m14.262s user 0m11.617s sys 0m0.016s14.262 秒かかりました。このような単純なプログラムではやはり C++ より少し遅いようです。 しかしもちろん Python や Scheme よりは圧倒的に早いので Sather は 簡単に高速なプログラムが書ける 魅力的な言語だといえます。 そして、もし速度をもっと向上させたければ C や Fortran とのインターフェースを利用することができます。
素数の密度は数が大きくなっていくと徐々に減少していくことがわかります。
なぜ Sather が普及しないのか不思議です。
![]() |
![]() |
![]() |
![]() |