Python Daily
2.57K subscribers
1.48K photos
53 videos
2 files
38.9K links
Daily Python News
Question, Tips and Tricks, Best Practices on Python Programming Language
Find more reddit channels over at @r_channels
Download Telegram
A Benchmark of matrix multiplication between C and Python

#Motivation

After a Python convention in my city (Python Brasil) me, a unqualified newbie and a friend of mine from the comp. sci. academia discussed with a few colleagues about the potential advantages of python, including its application in the scientific field for numerical applications.
One of their arguments was that runtime optimization provided by pypy offered a significant advantage over C.

Well without further ado, here are the source codes for each language.

#Source Codes

**python w/ numpy**

#! /usr/bin/python

import sys
import numpy as np
import time

n = int(sys.argv[1])
m1_file = sys.argv[2]
m2_file = sys.argv[3]

m1 = np.loadtxt(m1_file)
m2 = np.loadtxt(m2_file)
m3 = np.zeros(m1.shape)

start = time.time()
np.matmul(m1, m2, m3)
end = time.time()

print m3

print 'Time:', (end - start) * 1000.0


**python**

#! /usr/bin/python2

import sys
import time

n = int(sys.argv[1])
m1_file = sys.argv[2]
m2_file = sys.argv[3]

def readm(filename):
f = open(filename, 'r')
d = f.read()
mat = [[float(i) for i in row] for row in [s.split(' ')[0:n] for s in d.split('\n')[0:n]]]
return mat

m1 = readm(m1_file)
m2 = readm(m2_file)
m3 = [[0 for i in range(n)] for j in range(n)]

start = time.time();
for i in range(n):
for j in range(n):
for k in range(n):
m3[i][j] += (m1[i][k] * m2[k][j])
end = time.time();

for i in range(n):
for j in range(n):
print m3[i][j],
print ''

print 'Time:', (end - start) * 1000.0

**C**

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#ifdef ARRAY
void readm(FILE* f, int n, double* m) {
#endif
#ifdef MATRIX
void readm(FILE* f, int n, double** m) {
#endif
int i, j;
#ifdef ARRAY
for (i = 0; i < n * n; ++i)
fscanf(f, "%lf", &m[i]);
#endif

#ifdef MATRIX
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
fscanf(f, "%lf", &m[i][j]);
#endif
}

int main(int argc, char** argv) {
int i, j, k;
double start, end;
struct timeval tv_start, tv_end;

int n = atoi(argv[1]);
FILE* f1 = fopen(argv[2], "r");
FILE* f2 = fopen(argv[3], "r");

#ifdef ARRAY
double* m1 = (double*) malloc(sizeof(double) * n * n);
double* m2 = (double*) malloc(sizeof(double) * n * n);
double* m3 = (double*) malloc(sizeof(double) * n * n);

for (i = 0; i < n * n; ++i) m3[i] = 0;

readm(f1, n, m1);
readm(f2, n, m2);

gettimeofday(&tv_start, NULL);
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
for (k = 0; k < n; ++k)
m3[(i * n) + j] += (m1[(i * n) + k] * m2[(k * n) + j]);
gettimeofday(&tv_end, NULL);


for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j)
fprintf(stderr, "%lf ", m3[(i * n) + j]);
fprintf(stderr, "\n");
}
#endif

#ifdef MATRIX
double** m1 = (double**) malloc(sizeof(double*) * n);
double** m2 = (double**) malloc(sizeof(double*) * n);
double** m3 = (double**) malloc(sizeof(double*) * n);

for (i = 0; i < n; ++i) {
m1[i] = (double*) malloc(sizeof(double) * n);
m2[i] = (double*) malloc(sizeof(double) * n);
m3[i] = (double*) malloc(sizeof(double) * n);
}

for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
m3[i][j] = 0;

readm(f1, n, m1);
readm(f2, n, m2);

gettimeofday(&tv_start, NULL);
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
for (k = 0; k < n; ++k)
m3[i][j] += (m1[i][k] * m2[k][j]);
gettimeofday(&tv_end, NUL
How to interop between C and python


First of all, I want to make it clear that wrapping is a whole area, and what you're about to read is just the basics to get you started if you're interested in the subject.

basically every kind of wrapping code consists of you describing the bytes of each function (input and output), or the schema of each structure

For our example we will use a basic module of the 4 operations in C, (yes it's useless, it's just to demonstrate how it works)

#### Generate the linker object
Save it as **cmodule.c**

~~~c


int add(int x , int y){
return x + y;
}

int sub(int x , int y){
return x - y;
}

int mul(int x, int y){
return x * y;
}

double div(int x , int y){
return x /y;
}

#ifdef _WIN32

__declspec(dllexport) int add(int x , int y);
__declspec(dllexport) int sub(int x , int y);
__declspec(dllexport) int mul(int x, int y);
__declspec(dllexport) double div(int x , int y)
#endif


~~~

if you are on linux generete the linker object with

~~~shell
gcc -c -o cmodule.o -fPIC cmodule.c && gcc -shared -o cmodule.so cmodule.o
~~~


If you are on Windows Generate the linker with

~~~cmd
gcc -c -o

/r/Python
https://redd.it/13zw527