Skip to content

Instantly share code, notes, and snippets.

@mdmitry1
Last active February 8, 2025 19:29
Show Gist options
  • 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.13
import requests
from os import system, remove, popen, name as osname
from sys import argv
from os.path import realpath, basename
from re import sub
from rich import print as rprint
import tempfile
script_name = basename(realpath(argv[0]))
if(len(argv) < 2):
print("\nUsage:", script_name, "<output_file_name>\n")
exit(1)
try:
URL = "https://t5k.org/lists/small/millions/primes1.zip"
filter_cmd="grep -v '[a-z]' | tr ' ' '\012' | grep ^[1-9]"
if 'nt' == osname:
filter_cmd=sub(r"\n",r"\\n", filter_cmd)
response = requests.get(URL, verify=True)
with tempfile.NamedTemporaryFile() as primes1_zip:
primes1_zip.write(response.content)
prime_numbers=popen("unzip -p " + primes1_zip.name + " | " + filter_cmd).read().split('\n')
with open(argv[1],"w") as fp:
[print(prime_numbers[i], file=fp) for i in range(0,100008)]
except Exception as err:
rprint("\n[magenta] " + script_name + ":", "[red] ERROR: [/red]", "[red] " + str(err), "\n")
exit(1)
MODULE=primes_cython
VER=13
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 < 0 ) return 0;
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.
if nb_primes > 0:
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.13 $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)
n = int(argv[1])
if n >= 0:
result=primes_cython(int(argv[1]))
[print(x) for x in result]
#!/usr/bin/python3.13
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("primes_cython.pyx", language_level=3)
)
#!/usr/bin/python3.13
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%.expected.txt %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