Je ne l'ai pas utilisé ces cdef
classes ées lorsque le code écrit dans Cython, donc je vais laisser cette partie sur les avantages de cdef
types ées pour quelqu'un d'autre répondre. Sur le point des listes, bien que vous puissiez toujours utiliser les listes Python comme normales, vous aurez besoin de copy each member explicitly into a C array pour profiter pleinement des accélérations de l'écriture en C. Cependant, si les données sont stockées dans un tableau NumPy , vous pouvez simplement stocker un pointeur au début du tableau (en vous assurant que le tableau est contigu). Vous trouverez le tableau complet d'équivalence des types numpy et C ici: https://github.com/cython/cython/blob/master/Cython/Includes/numpy/__init__.pxd
En ce qui concerne les méthodes de classe cythonising, puisque la plupart du code Python peut fonctionner comme cela est sans modification Cython, vous pouvez définir votre classe dans Cython en utilisant class SomeClass:
normalement. Puisque les fonctions cdef
ne peuvent être appelées qu'à partir de Cython, vous voudrez probablement définir des méthodes cythonisées en dehors de la classe (de préférence typée pour améliorer les performances). À l'intérieur de la classe, vous pouvez utiliser le def
régulier (qui peut être appelé depuis Python) pour appeler leur contrepartie cytonisée.
Pour les classes Python majoritairement majoritairement que vous ne souhaitez pas déplacer dans Cython, vous pouvez utiliser une méthode similaire, mais vous ne disposez que de def
fonctions ed dans Cython appelant la version ed cdef
. Vous appelez ensuite les fonctions Cython de Python comme vous le feriez normalement lors de l'importation de modules.
Pour les structures de données qui ont uniquement besoin de résider en C et qui n'interagissent pas (beaucoup) avec Python, vous pouvez également envisager d'utiliser PyCapsule pour les stocker en tant qu'attributs de classe.
Edit:
À la lecture du commentaire sous chrisb réponse de, je suppose que vous voulez avoir un tableau 2D avec une longueur de ligne variable. Avant de plonger directement dans l'implémentation de la même structure de données en C, il est important de noter que C n'est pas Python. Il ne gérera pas automatiquement la longueur des listes pour vous, mais vous devrez gérer vous-même la mémoire (voir l'exemple dans le premier lien). Bien que ce soit la manière standard d'allouer dynamiquement de la mémoire, les programmeurs qui ne sont pas habitués à C (et Cython) ont tendance à ne pas toucher "malloc
et ses amis" puisque les pointeurs voleront autour. En plus de cela, les tableaux n'ont généralement pas de type de données mélangé, par ex. vous ne pouvez pas avoir à la fois des nombres et des chaînes dans le même tableau (si vous avez vraiment besoin de , il y a un moyen de le faire). À la lumière de cela, vous voudrez peut-être repenser votre structure de données. Par exemple, vous pouvez envisager de représenter les données avec des tableaux de longueur constante.Si votre tableau a une largeur maximale, vous pouvez échanger de la mémoire avec une facilité de programmation en utilisant un tableau NumPy.
Si vous êtes heureux de donner la gestion de la mémoire manuelle d'un coup, voici un exemple simple d'allocation de mémoire pour un tableau 2D de int
s:
from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
cdef int **generate_2D_array(int rows, int columns):
cdef int row
cdef int **parent = <int **>PyMem_Malloc(rows * sizeof(int*))
if not parent:
raise MemoryError()
for row in range(rows):
parent[row] = <int *>PyMem_Malloc(columns * sizeof(int))
if not parent[row]:
raise MemoryError()
return parent
Pour modifier la longueur d'une ligne, vous pouvez utiliser :
cdef void resize_row(int *row_pointer, int new_size):
PyMem_Realloc(row_pointer, new_size)
Lorsque vous avez terminé avec les données, souvenez-vous de désaffecter la mémoire en utilisant PyMem_Free
de façon similaire à l'allocation avec PyMem_Malloc
. La règle générale est: pour chaque PyMem_Malloc
vous utilisez, libérer la mémoire en utilisant exactement un PyMem_Free
, ni plus, ni moins. Et enfin, juste un mot d'avertissement, le fait de ne pas les utiliser de manière appropriée peut provoquer des erreurs de segmentation, des fuites de mémoire ou un comportement indéfini.
Salut! Merci d'avoir répondu! Cependant je ne savais pas que nous pouvions aussi utiliser des listes en cython! Est-ce mieux dans les performances par rapport à la liste Python? Est-ce que le gain de performance passe à cause de ça? Puis-je aussi déclarer de telles listes 2D en cython? –
Oui, 'list' peut être utilisé dans Cython, c'est exactement le même objet qu'une liste python, mais Cython sera un peu plus rapide en générant du code plus spécialisé et en ignorant la surcharge de l'interpréteur python. – chrisb
Si vous connaissez le type/la forme de vos données, vous feriez mieux d'utiliser un tableau numpy, qui peut être déclaré comme bidimensionnel comme suggéré par @Capow, une liste python ne peut pas (sera simplement une liste imbriquée de listes) – chrisb