Package: cinpy
You have no clue about C/C++, but want to boost Python using C/C++ code? Try this!cinpyis made for people who never coded in C/C++, but want to use C/C++ functions/algorithms found somewhere on the internet (GitHub, Stack Overflow, ChatGPT …) in their Python code to speed things up.This module is not for massive frameworks, only for small scripts/code snippets. It is very simple and straightforward to use.pip install cinpyPlease install:MSVC ..... C++ x64/x86 build tools from:https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&channel=Release&version=VS2022&source=VSLandingPage&passive=false&cid=2030Localize the following files (Version number might vary) and copy their path:vcvarsall_bat = r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat"cl_exe = r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\cl.exe"link_exe = r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\link.exe"ExamplesfromcinpyimportCreateCppDllvariable_for_function_creation=(r"!CT_DATA_DTYPE!_!CT_DATA_DTYPE2!_!C_FUNCTION_NAME!_!CT_DATA_DTYPE3!")appc=CreateCppDll(cfunctioname="cppradixsort",cfunction=rf"""!DTYPE_EXPLANATIONC!__declspec(dllexport) void{variable_for_function_creation}(!C_DATA_DTYPE! * indatav1,size_t size,!C_DATA_DTYPE2! * indatav2,!C_DATA_DTYPE3! * outdatav ){{std::vector<!C_DATA_DTYPE!> v(indatav1,indatav1 + size);concurrency::parallel_radixsort(begin(v), end(v));std::copy(v.begin(), v.begin()+size, outdatav);}}""",samedtypes=("!C_DATA_DTYPE!","!C_DATA_DTYPE3!"),modulename="radixsortcpp",variable_for_function_creation=variable_for_function_creation,cheader="""//#include <iostream>//#include <stdio.h>//#include <algorithm>    // std::replace_if#include <vector>       // std::vector//#include <functional>//#include <conio.h>#include <ppl.h>""",cfooter="",ignored_dtypes1=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float","double","long double","float complex","double complex","long double complex",),ignored_dtypes2=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float","double","long double","float complex","double complex","long double complex",),ignored_dtypes3=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float","double","long double","float complex","double complex","long double complex",),vcvarsall_bat=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat",cl_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\cl.exe",link_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\link.exe",compilerflags=("/std:c++17","/Ferelease","/EHsc","/MT","/O2","/bigobj"),)appc.compile_cpp_code()# compile and runfromcinpy.radixsortcppmoduleimportcppradixsortimportnumpyasnparr1=np.random.randint(0,10000,800000000)arr2=np.array([],dtype=arr1.dtype)sodi=cppradixsort(arr1,arr2,arr1.dtype)importnumpyasnpfromtimeimportperf_counterarr1=np.random.randint(0,10000,800000000)arr2=np.array([],dtype=arr1.dtype)start=perf_counter()sodi=cppradixsort(arr1,arr2,arr1.dtype)print('c++: ',perf_counter()-start)start=perf_counter()np.sort(arr1)print('numpy: ',perf_counter()-start)c++:5.262247000000002numpy:36.521482199999994importnumpyasnpfromtimeimportperf_counterarr1=np.random.randint(0,10000,800000000).tolist()start=perf_counter()arr1.sort()print('python: ',perf_counter()-start)python:158.9699383fromcinpyimportCreateCppDllvariable_for_function_creation=(r"!CT_DATA_DTYPE!_!CT_DATA_DTYPE2!_!C_FUNCTION_NAME!_!CT_DATA_DTYPE3!")appc=CreateCppDll(cfunctioname="cppbufferedsort",cfunction=rf"""!DTYPE_EXPLANATIONC!__declspec(dllexport) void{variable_for_function_creation}(!C_DATA_DTYPE! * indatav1,size_t size, !C_DATA_DTYPE2! * indatav2, !C_DATA_DTYPE3! * outdatav ){{std::vector<!C_DATA_DTYPE!> v(indatav1, indatav1 + size);concurrency::parallel_buffered_sort(begin(v), end(v));std::copy(v.begin(), v.begin()+size, outdatav);}}""",samedtypes=("!C_DATA_DTYPE!","!C_DATA_DTYPE3!"),modulename="bufferedsortcpp",variable_for_function_creation=variable_for_function_creation,cheader="""//#include <iostream>//#include <stdio.h>//#include <algorithm>    // std::replace_if#include <vector>       // std::vector//#include <functional>//#include <conio.h>#include <ppl.h>""",cfooter="",ignored_dtypes1=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),ignored_dtypes2=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),ignored_dtypes3=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),vcvarsall_bat=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat",cl_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\cl.exe",link_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\link.exe",compilerflags=("/std:c++17","/Ferelease","/EHsc","/MT","/O2","/bigobj"),)appc.compile_cpp_code()"""# Compile and runfrom cinpy.bufferedsortcppmodule import cppbufferedsortimport numpy as nparr1 = np.random.random(8000000)arr2 = np.array([],dtype=arr1.dtype)%timeit cppbufferedsort(arr1,arr2,arr1.dtype)%timeit np.sort(arr1)193 ms ± 7.74 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)568 ms ± 1.97 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)cppbufferedsort(arr1,arr2,arr1.dtype)Out[3]:array([5.84790262e-07, 6.10106611e-07, 6.50635063e-07, ...,9.99999442e-01, 9.99999492e-01, 9.99999790e-01])np.sort(arr1)Out[6]:array([5.84790262e-07, 6.10106611e-07, 6.50635063e-07, ...,9.99999442e-01, 9.99999492e-01, 9.99999790e-01])"""fromcinpyimportCreateCppDllvariable_for_function_creation=(r"!CT_DATA_DTYPE!_!CT_DATA_DTYPE2!_!C_FUNCTION_NAME!_!CT_DATA_DTYPE3!")appc=CreateCppDll(cfunctioname="variouscalculations",cfunction=rf"""!DTYPE_EXPLANATIONC!__declspec(dllexport) void{variable_for_function_creation}(!C_DATA_DTYPE! * indatav1,size_t size, !C_DATA_DTYPE2! * indatav2, !C_DATA_DTYPE3! * outdatav ){{concurrency::parallel_for (size_t(0), size, [&](size_t u){{outdatav[u] = indatav1[u] * indatav2[0] / indatav2[1] + indatav2[2] - indatav2[3];}});}}""",samedtypes=(),modulename="calcvarious",variable_for_function_creation=variable_for_function_creation,cheader="""//#include <iostream>//#include <stdio.h>//#include <algorithm>    // std::replace_if//#include <vector>       // std::vector//#include <functional>//#include <conio.h>#include <ppl.h>""",cfooter="",ignored_dtypes1=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),ignored_dtypes2=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),ignored_dtypes3=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),vcvarsall_bat=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat",cl_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\cl.exe",link_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\link.exe",compilerflags=("/std:c++17","/Ferelease","/EHsc","/MT","/O2","/bigobj"),)appc.compile_cpp_code()# Compile the code and run:fromcinpy.calcvariousmoduleimportvariouscalculationsimportnumpyasnpinputarray3np=np.random.randint(0,10000000,1000000).astype(np.float64)inputarray4np=np.array([40.2901,4.21,2.12,6.3])cp=variouscalculations(inputarray3np,inputarray4np,np.float64)nu=inputarray3np*40.2901/4.21+2.12-6.3print(cp)print(nu)[15388258.8046318385115406.4255582175231240.03558196...34228493.3404275668792824.635011986092819.36931117][15388258.8046318385115406.4255582175231240.03558196...34228493.3404275668792824.635011986092819.36931117]%timeitvariouscalculations(inputarray3np,inputarray4np,np.float64)2.04ms±124µsperloop(mean±std.dev.of7runs,100loopseach)%timeitinputarray3np*40.2901/4.21+2.12-6.310.2ms±63.6µsperloop(mean±std.dev.of7runs,100loopseach)fromcinpyimportCreateCppDllvariable_for_function_creation=(r"!CT_DATA_DTYPE!_!CT_DATA_DTYPE2!_!C_FUNCTION_NAME!_!CT_DATA_DTYPE3!")appc=CreateCppDll(cfunctioname="multiplybyarray",cfunction=rf"""!DTYPE_EXPLANATIONC!__declspec(dllexport) void{variable_for_function_creation}(!C_DATA_DTYPE! * indatav1,size_t size, !C_DATA_DTYPE2! * indatav2, !C_DATA_DTYPE3! * outdatav ){{concurrency::parallel_for (size_t(0), size, [&](size_t u){{outdatav[u] = indatav1[u] * indatav2[u];}});}}""",samedtypes=(),modulename="multiplyarrays",variable_for_function_creation=variable_for_function_creation,cheader="""//#include <iostream>//#include <stdio.h>//#include <algorithm>    // std::replace_if//#include <vector>       // std::vector//#include <functional>//#include <conio.h>#include <ppl.h>""",cfooter="",ignored_dtypes1=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),ignored_dtypes2=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),ignored_dtypes3=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),vcvarsall_bat=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat",cl_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\cl.exe",link_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\link.exe",compilerflags=("/std:c++17","/Ferelease","/EHsc","/MT","/O2","/bigobj"),)appc.compile_cpp_code()# compile and runfromcinpy.multiplyarraysmoduleimportmultiplybyarrayimportnumpyasnpinputarray3np=np.random.randint(0,1005000,8000000).astype(np.uint64)inputarray4np=np.random.randint(0,1022300,8000000).astype(np.uint64)%timeitmultiplybyarray(inputarray3np,inputarray4np,np.uint64)%timeitinputarray3np*inputarray4np18.1ms±757µsperloop(mean±std.dev.of7runs,100loopseach)26.6ms±163µsperloop(mean±std.dev.of7runs,10loopseach)multiplybyarray(inputarray3np,inputarray4np,np.uint64)Out[4]:array([218000641625,493834462272,38299985966,...,74381999748,168393582760,515058090867],dtype=uint64)inputarray3np*inputarray4npOut[5]:array([218000641625,493834462272,38299985966,...,74381999748,168393582760,515058090867],dtype=uint64)fromcinpyimportCreateCppDllvariable_for_function_creation=(r"!CT_DATA_DTYPE!_!CT_DATA_DTYPE2!_!C_FUNCTION_NAME!_!CT_DATA_DTYPE3!")appc=CreateCppDll(cfunctioname="multiplybynumber",cfunction=rf"""!DTYPE_EXPLANATIONC!__declspec(dllexport) void{variable_for_function_creation}(!C_DATA_DTYPE! * indatav1,size_t size, !C_DATA_DTYPE2! * indatav2, !C_DATA_DTYPE3! * outdatav ){{concurrency::parallel_for (size_t(0), size, [&](size_t u){{outdatav[u] = indatav1[u] * indatav2[0];}});}}""",samedtypes=(),modulename="mulbyonenumber",variable_for_function_creation=variable_for_function_creation,cheader="""//#include <iostream>//#include <stdio.h>//#include <algorithm>    // std::replace_if//#include <vector>       // std::vector//#include <functional>//#include <conio.h>#include <ppl.h>""",cfooter="",ignored_dtypes1=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),ignored_dtypes2=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),ignored_dtypes3=("bool",# "signed char",# "unsigned char",# "short",# "unsigned short",# "int",# "unsigned int",# "long",# "unsigned long",# "long long",# "unsigned long long","float",# "double","long double","float complex","double complex","long double complex",),vcvarsall_bat=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat",cl_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\cl.exe",link_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\link.exe",compilerflags=("/std:c++17","/Ferelease","/EHsc","/MT","/O2","/bigobj"),)appc.compile_cpp_code()# compile and runfromcinpy.mulbyonenumbermoduleimportmultiplybynumberimportnumpyasnpinputarray3np=np.random.randint(0,100000,8000000).astype(np.float64)inputarray4np=np.array([2.345122],dtype=np.float64)%timeitmultiplybynumber(inputarray3np,inputarray4np,np.float64)%timeitinputarray3np*inputarray4np[0]14.5ms±99µsperloop(mean±std.dev.of7runs,100loopseach)22.1ms±131µsperloop(mean±std.dev.of7runs,10loopseach)multiplybynumber(inputarray3np,inputarray4np,np.float64)Out[10]:array([221388.897288,123871.689162,40683.176456,...,222221.415598,73761.122266,69851.803892])inputarray3np*inputarray4np[0]Out[11]:array([221388.897288,123871.689162,40683.176456,...,222221.415598,73761.122266,69851.803892])# There is also a second version (if you need to pass more variables)fromcinpyimportCreateCppDllv2cppco=CreateCppDllv2(modulename="cppsort",# "module" will be added to "cppsort"# This is how to import it after compiling the code:# from cinpy.cppsortmodule import cppradixsortcheader="""#include <vector>       // std::vector#include <ppl.h>""",# Code before the functions in the .cpp file -> imports etc.cfooter="",# Code after the functions in the .cpp filecfunctioname="cppradixsort",# This is the name of the C++ function in Python, this is how you import it:# from cinpy.cppsortmodule import cppradixsortvar_variations={# cinpy creates various versions of the functions (I could not make# templates/function overloading work with Python) Create a dict with# all datadtypes that you want to use for each variable"!C_DATA_DTYPE1!":(# "bool","signed char","unsigned char","short","unsigned short","int","unsigned int","long","unsigned long","long long","unsigned long long",# "float",# "double",# "long double",# "float complex",# "double complex",# "long double complex",),"!C_DATA_DTYPE2!":("size_t",),"!C_DATA_DTYPE3!":(# "bool","signed char","unsigned char","short","unsigned short","int","unsigned int","long","unsigned long","long long","unsigned long long",# "float",# "double",# "long double",# "float complex",# "double complex",# "long double complex",),"!C_DATA_DTYPE4!":("size_t",),"!C_DATA_DTYPE5!":(# "bool","signed char","unsigned char","short","unsigned short","int","unsigned int","long","unsigned long","long long","unsigned long long",# "float",# "double",# "long double",# "float complex",# "double complex",# "long double complex",),"!C_DATA_DTYPE6!":("size_t",),},dtypemustbeequal=[("!C_DATA_DTYPE1!","!C_DATA_DTYPE3!","!C_DATA_DTYPE5!")],# "!C_DATA_DTYPE1!", "!C_DATA_DTYPE3!", "!C_DATA_DTYPE5!" will always have the same Datatypefu=rf"""__declspec(dllexport) void variable_for_function_creation(!C_DATA_DTYPE1! * indatav1,!C_DATA_DTYPE2!  size1,!C_DATA_DTYPE3! * indatav2,!C_DATA_DTYPE4!  size2,!C_DATA_DTYPE5! * indatav3,!C_DATA_DTYPE6! size3  ){{std::vector<!C_DATA_DTYPE1!> v(indatav1,indatav1 + size1);concurrency::parallel_radixsort(begin(v), end(v));std::copy(v.begin(), v.begin()+size1, indatav3);std::vector<!C_DATA_DTYPE1!> v2(indatav1, indatav1 + size1);concurrency::parallel_buffered_sort(begin(v2), end(v2));std::copy(v2.begin(), v2.begin()+size1, indatav2);}}""",# The C++ code, use the keys in the dict for the data types, don't change the function name:  variable_for_function_creation)cppco.compile_cpp_code(vcvarsall_bat=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat",cl_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\cl.exe",link_exe=r"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x64\link.exe",compilerflags=("/std:c++20","/Ferelease","/EHsc","/MT","/O2","/bigobj"),)# Compile the code#import the compiled codefromcinpy.cppsortmoduleimportcppradixsortimportnumpyasnpinputarray=np.array([6,3,2,64,2,46],dtype=np.uint8)npbufferedsort=np.zeros_like(inputarray)npradixsort=np.zeros_like(inputarray)len1=inputarray.sizelen2=npbufferedsort.sizelen3=npradixsort.size# arguments always start with v + number, data dtype should be detected automaticallycppradixsort(v0=inputarray,v1=len1,v2=npbufferedsort,v3=len2,v4=npradixsort,v5=len3,)print(inputarray)print(npbufferedsort)print(npradixsort)# results# [ 6  3  2 64  2 46]# [ 2  2  3  6 46 64]# [ 2  2  3  6 46 64]