| Extending & Embedding Python Using C - Pi |
| Written by Mike James | |||
| Monday, 02 October 2023 | |||
Page 1 of 2 Discover what goes into coding a Python extension module and see how fast C is when compared to Python by using it to compute Pi. Extending & Embedding Python Using CBy Mike JamesBuy from Amazon. ContentsPreface
<ASIN:B0CK3X93KF> In chapter but not in this extract
Computing Pi – How Fast?As a second simple example, we can use a very simple computation to demonstrate the potential speed advantages that a C extension module offers. You can compute pi using the very simple series: pi = 4*(1-1/3+1/5-1/7 ... ) This is very easy to implement, we just need to generate the odd integers, but to get pi to a reasonable number of digits you have to compute a lot of terms. In other words, this series is very slow to converge. The simple-minded approach is to write something like: import time
def myPi(m,n):
pi=0
for k in range(m,n+1):
s= 1 if k%2 else -1
pi += s / (2 * k - 1)
return 4*pi
This computes the sum from m to n. A main program to make use of this function is: if __name__ == '__main__':
N=10000000
t1=time.perf_counter()
pi=myPi(1,N)
t2=time.perf_counter()
print((t2-t1)*1000)
print(pi)
If you try this out you will find that it gives pi to about five digits, which is not good for so many terms, but it is a good example to convert to a C extension. The details of initializing the module follow the usual steps and the function is a fairly obvious translation of the Python: #define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject * Pi(PyObject *self, PyObject *args)
{
int m, n;
double pi,s;
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
pi=0;
for(int k=m;k<n;k++){
s=1;
if(k%2==0)s=-1;
pi=pi+s/(2*k-1);
}
return PyFloat_FromDouble(4*pi);
}
static PyMethodDef AddMethods[] = {
{"myPi", Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods
};
PyMODINIT_FUNC PyInit_Pi(void) {
return PyModule_Create(&addmodule);
}
The only real changes are to the names used for the module and function. Task.json also needs to be updated. The args for Windows is: "args": [
"/Zi",
"/EHsc",
"/nologo",
"/IC:/Users/user/AppData/Local/Programs
/Python/Python311/include",
"${file}",
"/link /dll /OUT:Pi.pyd
/LIBPATH:C:/Users/user/AppData/Local/
Programs/Python/Python311/libs"
For Linux it is: "args": [ With these changes the module should compile. If not go back to the instructions in chapters 2 and 3.
|
|||
| Last Updated ( Monday, 02 October 2023 ) |

