Warum ist die Matrixmultiplikation mit numpy schneller als mit ctypes in Python?
Ich habe versucht, den schnellsten Weg zur Matrixmultiplikation zu finden und habe drei verschiedene Wege ausprobiert:
Pure Python-Implementierung: keine Überraschungen.Numpy Implementierung mitnumpy.dot(a, b)
Schnittstelle zu C mitctypes
Modul in Python.Dies ist der C-Code, der in eine gemeinsam genutzte Bibliothek umgewandelt wird:
<code>#include <stdio.h> #include <stdlib.h> void matmult(float* a, float* b, float* c, int n) { int i = 0; int j = 0; int k = 0; /*float* c = malloc(nay * sizeof(float));*/ for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { int sub = 0; for (k = 0; k < n; k++) { sub = sub + a[i * n + k] * b[k * n + j]; } c[i * n + j] = sub; } } return ; } </code>
Und der Python-Code, der es aufruft:
<code>def C_mat_mult(a, b): libmatmult = ctypes.CDLL("./matmult.so") dima = len(a) * len(a) dimb = len(b) * len(b) array_a = ctypes.c_float * dima array_b = ctypes.c_float * dimb array_c = ctypes.c_float * dima suma = array_a() sumb = array_b() sumc = array_c() inda = 0 for i in range(0, len(a)): for j in range(0, len(a[i])): suma[inda] = a[i][j] inda = inda + 1 indb = 0 for i in range(0, len(b)): for j in range(0, len(b[i])): sumb[indb] = b[i][j] indb = indb + 1 libmatmult.matmult(ctypes.byref(suma), ctypes.byref(sumb), ctypes.byref(sumc), 2); res = numpy.zeros([len(a), len(a)]) indc = 0 for i in range(0, len(sumc)): res[indc][i % len(a)] = sumc[i] if i % len(a) == len(a) - 1: indc = indc + 1 return res </code>
Ich hätte gewettet, dass die Version mit C schneller gewesen wäre ... und ich hätte verloren! Unten ist mein Benchmark, der zu zeigen scheint, dass ich es entweder falsch gemacht habe oder dassnumpy
ist blöd schnell:
Ich würde gerne verstehen, warum das so istnumpy
Version ist schneller als diectypes
Version, ich spreche nicht einmal über die reine Python-Implementierung, da es irgendwie offensichtlich ist.