2017-05-25 3 views
1

Je me demandais si quelqu'un pourrait me conseiller s'il y a une meilleure approche/plus rapide pour lire les données de mon programme C qui produit deux listes de taille n. J'utilise ctypes pour appeler le programme C.Une méthode plus rapide pour convertir un tableau ctypes en une liste python?

La boucle I ci-dessous fonctionne en itérant sur un certain nombre d'analyses. Pour chaque analyse deux listes sont produites (msX, msY). Les données c_float sont extraites à l'aide de la boucle de compréhension de liste. Existe-t-il un moyen meilleur/plus rapide de convertir le c_float_Array obtenu à partir de mzP et mzI en msX et msY? Faites-moi savoir si ma question n'est pas claire.

for scan in xrange(nScans): 
    mzP = (c_float * nPoints)() # pointer to list 1, c_float_Array 
    mzI = (c_float * nPoints)() # pointer to list 2, c_float_Array 
    mlLib.readData(filePointer, 1, scan, byref(mzP), byref(mzI)) 
    # The slow part... 
    msX = [mzP[i] for i in xrange(nPoints)] # list with mzP data 
    msY = [mzI[i] for i in xrange(nPoints)] # list with mzI data 

Merci pour votre aide à l'avance.

+0

Essayez avec PyPy https://www.pypy.org avec CPython il n'y a rien plus rapide que la compréhension de la liste. –

+1

'msX = mzP [:]' serait plus rapide qu'une compréhension de liste, mais pourquoi avez-vous besoin d'une liste au lieu d'utiliser directement le tableau ctypes? Si un tableau ctypes manque une méthode dont vous avez besoin, peut-être un 'array.array' suffira-t-il? En commençant par 'msX = array.array ('f', [0]) * nPoints', vous pouvez obtenir un tableau ctypes qui le partage via' mzP = (c_float * nPoints) .from_buffer (msX) '. – eryksun

+0

Merci pour les commentaires. J'ai essayé votre première suggestion et cela réduit le temps d'exécution à env. 45% ce qui est génial. Je vais examiner votre autre suggestion pour voir si cela conviendra. Merci! – munieq11

Répondre

1

Si vous préférez, vous pouvez convertir en un tableau avec np.ndarray:

msX = np.ndarray((nPoints,), 'f', mzP, order='C')  
msY = np.ndarray((nPoints,), 'f', mzI, order='C') 
+0

Il augmente la vitesse d'environ 20% par rapport à ce que @eryksun a suggéré. Merci! – munieq11

1

La réponse est d'utiliser NumPy. Vous pouvez utiliser NumPy pour allouer un tableau, passer un pointeur à ses données à votre API C qui le peuplera, puis à la fin si vous avez désespérément besoin d'un list, vous pouvez appeler tolist() sur le tableau NumPy. Cependant, vous constaterez probablement que le fait de conserver les données stockées dans un tableau NumPy au lieu d'une liste vous permet d'accélérer le traitement en aval.