[PYTHON] Beschleunigen Sie die Verarbeitung mithilfe des C ++ - Vektors unordered_map intern in Cython

Überblick

Mit Cython können Sie Python vorkompilieren und in äquivalenten C / C ++ - Code verwenden. Fast die gesamte Python-Syntax wird unterstützt. Durch einfaches Kompilieren von vorhandenem Python-Code mit Cython wird die Ausführungsgeschwindigkeit um mehrere zehn Prozent verbessert.

Eines der interessanten Dinge an Cython ist, dass Sie damit C- und C ++ - Datentypen direkt aus Ihrem Python-Code (Cython) verwenden können.

Verwenden Sie dieses Mal anstelle von Pythons Diktat die ungeordnete Karte von C ++ und anstelle von list den Vektor direkt aus dem Cython-Code.

Experiment

Wenn Sie list und dict als Arrays und vector und unordered_map als assoziative Arrays verwenden, generieren Sie jeweils 1 Million Mal int key-Arrays und weisen Sie sie zu und bezeichnen Sie sie als assoziative Arrays, um die Leistung zu vergleichen. schauen.

Der Cython-Code verwendet .pyx anstelle von .py, daher lautet der Dateiname cython_stl_experiment.pyx.

cython_cpp_experiment.pyx


# distutils: language=c++
# -*- coding: utf-8 -*-

import time
from libcpp.vector cimport vector
from unordered_map cimport unordered_map


cdef vector[int] cpp_keys = [k for k in range(1000000)]
keys = [k for k in range(1000000)]

cdef unordered_map[int, bint] cpp_dict
py_dict = {}


cpdef test_python_dict_set():
    for key in keys:
        py_dict[key] = True


cpdef test_python_dict_lookup():
    for key in keys:
        assert py_dict[key] == True


cpdef test_cpp_umap_set():
    cdef int key
    for key in cpp_keys:
        cpp_dict[key] = True


cpdef test_cpp_umap_lookup():
    for key in cpp_keys:
        assert cpp_dict[key] == True


def run():
    start = time.clock()
    test_python_dict_set()
    print 'test_python_dict_set:', time.clock() - start

    start = time.clock()
    test_python_dict_lookup()
    print 'test_python_dict_lookup:', time.clock() - start

    start = time.clock()
    test_cpp_umap_set()
    print 'test_cpp_umap_set:', time.clock() - start

    start = time.clock()
    test_cpp_umap_lookup()
    print 'test_cpp_umap_lookup:', time.clock() - start

Versuchen Sie, den obigen Code auszuführen.

In [1]: import cython_cpp_experiment
In [2]: cython_cpp_experiment.run()
test_python_dict_set: 0.116818
test_python_dict_lookup: 0.064986
test_cpp_umap_set: 0.094401
test_cpp_umap_lookup: 0.01363

Obwohl sich die Zuweisungszeit für das assoziative Array nur um etwas weniger als 20% ändert, kann der Suchvorgang um etwa das Fünffache beschleunigt werden.

schließlich

Cython hat eine Funktion implementiert, die den Typ der Zeichenfolge (Byte) und std :: string, list und std :: vector usw. automatisch entsprechend dem Kontext konvertiert und eine relativ Python-ähnliche Beschreibung beibehält. Dies ist sehr praktisch, da Sie den C ++ - Datentyp direkt verwenden können.

Selbst im obigen Code wird der Vektor mit for… in… in Python-ähnlicher Syntax behandelt (intern wird ein C ++ - Iterator generiert und verarbeitet).

Referenz: Using C++ in Cython / Standard library: http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#standard-library

Möglicherweise hören Sie Leute sagen, dass Sie Erweiterungen in C schreiben oder ctypes verwenden sollten, aber Cython, das nur einen Teil des Codes wie die Wiederholung in Python beschleunigen kann, kann verschiedene Verwendungszwecke haben. Überlegen.

Den diesmal verwendeten Code finden Sie auch hier. https://github.com/ikuyamada/cython-cpp-experiment

Recommended Posts

Beschleunigen Sie die Verarbeitung mithilfe des C ++ - Vektors unordered_map intern in Cython
Verwenden des Python-Modus in der Verarbeitung
Vergleich der Stapelverarbeitungsgeschwindigkeit nach Sprache
Beim Lesen der C ++ - Struktur mit Cython
Beschleunigen Sie die C / C ++ - Kompilierung mit ccache