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
#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
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
Reddit
From the Python community on Reddit
Explore this post and more from the Python community