Rufen Sie C von Python mit DragonFFI auf

Es scheint, dass das LLVM-Projekt einen FFI namens Dragon FFI veröffentlicht hat. Blog zeigt ein Beispiel für das Aufrufen der C-Sprache aus Python.

FFI ist übrigens eine Abkürzung für Foreign Function Interface, ein Mechanismus, mit dem Sie Funktionen verwenden können, die in einer Programmiersprache in einer anderen definiert sind. Beispielsweise implementiert Rust, das als Ersatz für C erstellt wurde, FFI, um C aufzurufen.

Ich habe mit Pydffi gespielt, DragonFFIs Python Wrapper.

Umgebungseinstellung

Für Python habe ich "Python 3.6.3 :: Anaconda, Inc." verwendet, das von pyenv installiert wurde. Die Bibliothek war einfach mit pip zu installieren.

pip install pydffi

Ich werde es vorerst mit Fibonacci versuchen

Ich wollte eigentlich nichts tun, also habe ich eine Fibonacci-Sequenzfunktion in Python und C implementiert. Die Idee ist, dass eine in C geschriebene Funktion eine schnelle Ausführungsgeschwindigkeit haben sollte, daher wäre es interessant, den numerischen Wert zu sehen.

Python-Funktionen

def f(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return f(n-1)+f(n-2)

print(f(30))

pydffi

C-Funktion

Definieren Sie eine solche Funktion f.

int f(int n) {
  if (n == 0) {
    return 0;
  } else if (n == 1) {
    return 1;
  } else {
    return f(n-1) + f(n-2);
  }
}

Rufen Sie C mit pydffi aus Python auf

Rufen Sie die in C definierte Funktion f in Python auf. Mit pydffi war es sehr einfach zu schreiben!

import pydffi

with open("cfunc/fibonacci_opt.c") as f:
    c_src = "".join(f.readlines())

F = pydffi.FFI()
CU = F.compile(c_src)
print(int(CU.funcs.f(30)))

Ergebnis

Wird bei N = 30 ausgeführt. Es ist eine Funktion, die überhaupt nicht optimiert wurde, daher ist es natürlich, dass die C-Sprache schneller ist.

Python-Funktionen C-Funktion(pydffi)
0.3381[sec] 0.0496[sec]

Versuchen Sie ein wenig zu optimieren

Übrigens, wenn Sie Python durch Notizen optimieren, sieht es so aus. (schnell!) Der Algorithmus ist wichtig.

Python(Memo)
0.00005[sec]
memo = [0] * 1000

def f(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1

    if memo[n]:
        return memo[n]

    m = f(n-1)+f(n-2)
    memo[n] = m
    return m

print(f(30))

Ich habe es auch mit MatMul versucht

Ich wollte ein anderes Beispiel, also implementierte ich die Matrixmultiplikation, das sogenannte Matmul. Diesmal ist Numpy auch ein Vergleichsziel.

Python-Funktionen

A = [random.random() for _ in range(N) for _ in range(N)]
B = [random.random() for _ in range(N) for _ in range(N)]
C = [0.0 for _ in range(N) for _ in range(N)]

for i in range(N):
    for j in range(N):
        for k in range(N):
            C[i * N + j] += A[i * N + k] * B[k * N + j]

pydffi

C-Funktion

void matmul(double *A, double *B, double *C, int N) {
  int i, j, k;
  for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++) {
      for (k = 0; k < N; k++) {
        C[i * N + j] += A[i * N + k] * B[k * N + j];
      }
    }
  }
}

Rufen Sie C von Python aus auf

# read c source
with open("cfunc/matmul.c") as f:
    c_src = "".join(f.readlines())

# initialize
FFI = pydffi.FFI()
CU = FFI.compile(c_src)

# create array objects & set values
arr_A = pydffi.CArrayObj(FFI.arrayType(FFI.DoubleTy, N*N))
arr_B = pydffi.CArrayObj(FFI.arrayType(FFI.DoubleTy, N*N))
arr_C = pydffi.CArrayObj(FFI.arrayType(FFI.DoubleTy, N*N))
for i in range(N*N):
    arr_A.set(i, A[i])
    arr_B.set(i, B[i])
    arr_C.set(i, 0.0)

# execute c matmul
start = time.time()
CU.funcs.matmul(arr_A, arr_B, arr_C, N)
print("C(FFI):{:.5f}[sec]".format(time.time() - start))

numpy

np_A = np.array(A).reshape(N, N)
np_B = np.array(B).reshape(N, N)
np_C = np.matmul(np_A, np_B)

Ergebnis

N=256 Immerhin ist die C-Funktion schnell. Und Numpy ist erwartungsgemäß am schnellsten. Nun, C ist nur eine Dreifachschleife, also gibt es Raum für mehr Optimierung. (⇒ Für diejenigen, die an der Optimierung von matmul interessiert sind, ist hier hilfreich.)

Python-Funktionen C-Funktion(pydffi) numpy
7.1067[sec] 0.0329[sec] 0.0281[sec]

N=1024

Python-Funktionen C-Funktion(pydffi) numpy
Keine Messung 7.4422[sec] 0.0769[sec]

Schlußfolgerung

Recommended Posts

Rufen Sie C von Python mit DragonFFI auf
Rufen Sie popcount von Ruby / Python / C # auf
Rufen Sie Python von Nim mit Nimpy auf
Rufen Sie C / C ++ von Python auf dem Mac auf
Rufen Sie die c-Sprache von Python aus auf (python.h)
Verwenden von C ++ - Funktionen aus Python mit pybind11
Wickeln Sie C mit Cython für Python ein
Rufen Sie Python-Skripte aus Embedded Python in C ++ / C ++ auf
Wrap C ++ mit Cython zur Verwendung von Python
Rufen Sie CPLEX von Python aus auf (DO cplex)
Rufen Sie die API mit python3 auf.
Mit Skype benachrichtigen Sie mit Skype von Python!
Rufen wir Ihre eigene C ++ - Bibliothek mit Python auf (Einstellungen)
[Python] So rufen Sie eine Funktion von c aus Python auf (ctypes edition)
Rufen Sie Matlab von Python zur Optimierung auf
Rufen Sie C-Sprachfunktionen von Python auf, um mehrdimensionale Arrays auszutauschen
Löse ABC163 A ~ C mit Python
Erstellen Sie Awaitable mit der Python / C-API
Verwenden von Rstan aus Python mit PypeR
Installieren Sie Python von der Quelle mit Ansible
Löse ABC168 A ~ C mit Python
Führen Sie Aprili von Python auf Orange aus
Tipps zum Aufrufen von Python von C.
Führen Sie Python-Code über die C # -GUI aus
AtCoder ABC 114 C-755 mit Python3 gelöst
Löse ABC162 A ~ C mit Python
Führen Sie Python-Skripte synchron von C # aus
Löse ABC167 A ~ C mit Python
Löse ABC158 A ~ C mit Python
Laden Sie fbx aus Python mitinema4d
Bearbeiten von Kintondaten mit dem Python & C Data ODBC-Treiber von AWS Lambda
Übergeben Sie die Liste von Python an C ++ als Referenz in pybind11
Rufen Sie mit ctypes Ihre eigene gemeinsam genutzte Bibliothek in C-Sprache von Python aus auf
Sammeln von Informationen von Twitter mit Python (Twitter API)
Empfangen Sie Textdaten von MySQL mit Python
Holen Sie sich HTML von Element mit Python-Selen
[Hinweis] Mit Python Daten von PostgreSQL abrufen
Spielen Sie eine Audiodatei von Python mit Interrupt ab
Erstellen Sie mit python3 eine Wortwolke aus Ihrem Tweet
Tweet von Python mit Twitter Developer + Tweepy
[C] [Python] Lesen mit AquesTalk unter Linux
Geschäftseffizienz von Grund auf mit Python
Mit openssl verschlüsselte Dateien werden mit openssl aus Python entschlüsselt
Bearbeiten von Azure CosmosDB aus Python Part.2
Bildaufnahme von der Kamera mit Python + OpenCV
Erste Schritte mit Dynamo von Python Boto
Versuchen Sie, Python von Ruby aus mit Sparsamkeit aufzurufen
Scraping von einer authentifizierten Site mit Python
Generieren Sie mit Python eine C-Sprache aus dem S-Ausdruck
Rufen Sie APIGateWay mit APIKey in Python-Anforderungen auf
Aufrufbefehle von Python (Windows Edition)
RaspberryPi L Chika mit Python und C #
[C, C ++, Python, JavaScript] L Chika mit Edison
FizzBuzz in Python3
Scraping mit Python
Statistik mit Python