Skip to content

Instantly share code, notes, and snippets.

@mdmitry1
Last active February 24, 2024 07:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdmitry1/7b4c06e581515fcf097093eacf628aa3 to your computer and use it in GitHub Desktop.
Save mdmitry1/7b4c06e581515fcf097093eacf628aa3 to your computer and use it in GitHub Desktop.
Prime numbers calculation in C++, Cython an Python
#!/usr/bin/python3.11
import requests
from os import popen, name as osname
from sys import argv
from os.path import realpath, basename
from re import sub
if(len(argv) < 2):
script_name = basename(realpath(argv[0]))
print("\nUsage:", script_name, "<output_file_name>\n")
exit(1)
URL = "https://primes.utm.edu/lists/small/100000.txt"
response = requests.get(URL, verify=True)
filter_cmd="grep -v '[a-z]' | tr ' ' '\012' | grep ^[1-9]"
if 'nt' == osname:
filter_cmd=sub(r"\n",r"\\n", filter_cmd)
line_count=popen(filter_cmd + " > " + argv[1],"w").write(response.content.decode('utf-8'))
MODULE=primes_cython
VER=11
EXT=cpython-3$(VER)-$(HOSTTYPE)-gnu.so
SO=$(MODULE).$(EXT)
%: %.cpp
g++ -O2 -o $@ $<
strip $@
%.$(EXT): %_setup.py %.pyx
python3.$(VER) $< build_ext -i
strip $@
-rm -rf build
all: $(SO) primes_cpp
clean:
-rm -rf $(SO) $(MODULE).cpp primes_cpp
MODULE=primes_cython
EXT=cp310-mingw_x86_64_ucrt.pyd
SO=$(MODULE).$(EXT)
PATH=/ucrt64/bin:/usr/bin
%: %.cpp
g++ -O2 -o $@ $<
/usr/bin/strip $@
%.$(EXT): %_setup.py %.pyx
/ucrt64/bin/python3 $< build_ext -i
/usr/bin/strip $@
-rm -rf build
all: $(SO) primes_cpp
clean:
-rm -rf $(SO) $(MODULE).cpp primes_cpp
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
typedef vector<int> int_vector;
typedef vector<int>::const_iterator int_vector_citerator;
typedef pair<int_vector_citerator, int_vector_citerator> cint_pair;
class sieve {
public:
~sieve() { delete result; }
sieve(int n) { mn = n; result = new int_vector(n, 0); }
void primes();
inline const cint_pair result_pair() const {
return cint_pair(result->cbegin(), result->cend());
}
private:
int_vector *result;
int mn;
};
void sieve::primes( ) {
int_vector& p = *result;
for(int n = 2, np = 0; np < mn; n++) {
int i ;
int ilast = ceil(sqrt(np));
for( i = 0; i < ilast && n % p[i]; i++ );
if( i == ilast ) p[np++] = n;
}
}
ostream& operator<<( ostream& os, const sieve& s ) {
cint_pair result = s.result_pair();
int_vector_citerator vit = result.first;
int_vector_citerator vend = result.second;
while(vit < vend) os << *vit++ << endl;
return os;
}
int main(int argc, char**argv) {
if(argc < 2) {
auto s = string(*argv);
auto exe_name = s.substr(s.find_last_of("/\\") + 1);
cout << endl << "Usage: " << exe_name << " <n>" << endl << endl;
return 1;
}
auto input_string = string(argv[1]);
istringstream input_stream(input_string);
int n;
input_stream >> n;
if( n < 1 ) {
cerr << endl << "ERROR: n should be positive number" << endl << endl;
return 1;
}
sieve my_sieve = sieve(n);
my_sieve.primes();
cout << my_sieve;
return 0;
}
# distutils: language=c++
from libcpp.vector cimport vector
from libc.math cimport sqrt, ceil
def primes_cython(unsigned int nb_primes):
cdef int n = 2, i
cdef vector[int] p
p.reserve(nb_primes) # allocate memory for 'nb_primes' elements.
p.push_back(n)
while p.size() < nb_primes: # size() for vectors is similar to len()
plast = int(ceil(sqrt(n)))+1
for i in range(2,plast):
if n % i == 0: break
else: p.push_back(n) # push_back is similar to append()
n += 1
# Vectors are automatically converted to Python lists when converted to Python objects.
return p
#!/usr/bin/tcsh -f
"/bin/true" '''\'
setenv PYTHONPATH `realpath $0 | xargs dirname`
exec python3.11 $0 $*
'''
from primes_cython import primes_cython
from sys import argv
from os.path import basename
if len(argv) < 2:
print("\nUsage:",basename(argv[0]),"<n>\n")
exit(1)
result=primes_cython(int(argv[1]))
#for p in res: print(p)
[print(x) for x in result]
#!/usr/bin/python3.11
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("primes_cython.pyx", language_level=3)
)
#!/usr/bin/python3.11
from sys import argv
from os.path import realpath, basename
from math import ceil, sqrt
def primes_python(nb_primes):
if nb_primes < 1:
return []
p=[n:=2]
while len(p) < nb_primes:
plast = int(ceil(sqrt(n)))+1
for i in range(2,plast):
if n % i == 0: break
else: p.append(n)
n += 1
return p
if(len(argv) < 2):
script_name = basename(realpath(argv[0]))
print("\nUsage:", script_name, "<n>\n")
exit(1)
result=primes_python(int(argv[1]))
[print(x) for x in result]
#!/usr/bin/tcsh -f
set script_realpath=`realpath $0`
set script_path=$script_realpath:h
set n=100008
\rm -f ${n}.{expected,cpp,cython,python}.txt
${script_path}/create_expected.py ${n}.expected.txt
time ${script_path}/primes_cpp $n > ${n}.cpp.txt
time ${script_path}/primes_cython_run.py $n > ${n}.cython.txt
time ${script_path}/primes_python.py $n > ${n}.python.txt
sum ${n}.{expected,cpp,cython,python}.txt
@echo off
set PATH=%PATH%;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin
set N=100008
del %N%.* 2> nul
C:\msys64\ucrt64\bin\python3.exe %~dp0\create_expected.py %N%.expected.txt
C:\msys64\usr\bin\time.exe %~dp0\primes_cpp.exe %N% > %N%.primes_cpp.txt
C:\msys64\usr\bin\time.exe C:\msys64\ucrt64\bin\python3.exe %~dp0\primes_cython_run.py %N% > %N%.primes_cython.txt
C:\msys64\usr\bin\time.exe C:\msys64\ucrt64\bin\python3.exe %~dp0\primes_python.py %N% > %N%.primes_python.txt
dos2unix %N%.primes_cpp.txt %N%.primes_cython.txt %N%.primes_python.txt
sum %N%.expected.txt %N%.primes_cpp.txt %N%.primes_cython.txt %N%.primes_python.txt
#!/usr/bin/bash -f
script_realpath=$(realpath $0)
script_path=$(dirname $script_realpath)
os=$(uname)
if [[ $os =~ .*NT.* ]]; then
python_exe=/c/msys64/ucrt64/bin/python3
time_exe_prefix=/c/msys64
else
python_exe=""
time_exe_prefix=""
fi
n=100008
\rm -f $n.{expected,cpp,cython,python}.txt 2> /dev/null
$python_exe $script_path/create_expected.py $n.expected.txt
$time_exe_prefix/usr/bin/time $script_path/primes_cpp $n > $n.cpp.txt
$time_exe_prefix/usr/bin/time $python_exe $script_path/primes_cython_run.py $n > $n.cython.txt
$time_exe_prefix/usr/bin/time $python_exe $script_path/primes_python.py $n > $n.python.txt
if [[ $os =~ .*NT.* ]]; then
dos2unix $n.{expected,cpp,cython,python}.txt
fi
sum $n.{expected,cpp,cython,python}.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment