[PYTHON] Accélérez le traitement en utilisant le vecteur C ++, unordered_map en interne en Cython

Aperçu

Cython vous permet de précompiler et d'utiliser Python dans un code C / C ++ équivalent. Presque toute la syntaxe Python est prise en charge, et la simple compilation du code Python existant avec Cython améliorera la vitesse d'exécution de dizaines de pour cent.

L'une des choses intéressantes à propos de Cython est qu'il vous permet d'utiliser des types de données C et C ++ directement à partir de votre code Python (Cython).

Cette fois, au lieu du dict de Python, utilisez unordered_map de C ++, et au lieu de list, utilisez le vecteur directement à partir du code Cython.

Expérience

L'utilisation de list et dict comme tableaux et vector et unordered_map comme tableaux associatifs, respectivement, génère des tableaux de clés int 1 million de fois chacun, et les attribue et se réfère à eux comme des clés pour comparer les performances. regarder.

Le code Cython utilise .pyx au lieu de .py, le nom de fichier est donc 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

Essayez d'exécuter le code ci-dessus.

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

Bien que le temps d'affectation au tableau associatif ne change que d'un peu moins de 20%, le processus de recherche peut être accéléré d'environ 5 fois.

à la fin

Cython a implémenté une fonction qui convertit automatiquement le type de chaîne de caractères (octet) et std :: string, list et std :: vector, etc. en fonction du contexte, et conserve une description relativement semblable à Python. C'est très pratique car vous pouvez utiliser le type de données C ++ directement tel quel.

Même dans le code ci-dessus, le vecteur est géré avec «for… in…» dans une syntaxe de type Python (en interne, un itérateur C ++ est généré et traité).

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

Vous pouvez entendre des gens dire que vous devez écrire des extensions en C ou utiliser des ctypes, mais Cython, qui ne peut accélérer que certains codes tels que la répétition en Python, peut avoir diverses utilisations. pense.

Aussi, le code utilisé cette fois peut être trouvé ici. https://github.com/ikuyamada/cython-cpp-experiment

Recommended Posts

Accélérez le traitement en utilisant le vecteur C ++, unordered_map en interne en Cython
Utilisation du mode Python dans le traitement
Comparaison de la vitesse de traitement de la pile par langue
Lors de la lecture d'une structure C ++ avec Cython
Accélérer la compilation C / C ++ avec ccache