2011-11-09 16 views
14

Tengo algunas funciones escritas en C para un proyecto de juego. Estas funciones son llamadas bastante (alrededor de 2000-4000 veces por segundo). Las funciones están escritas en C para velocidad bruta.ctypes vs extensión C

Ahora, la forma más fácil para mí de incluir estas funciones en Python es usar ctypes. La alternativa es escribir una extensión C a Python en torno a estas funciones (lo que requiere un esfuerzo extra). Entonces me pregunté, sin incluir la carga inicial de la DLL, ¿qué tan grande es la sobrecarga de ctypes?


estoy usando Python 2.7 (la liberación CPython estándar), y no querer usar una biblioteca externa como Cython.

Sé que esta pregunta se ha hecho antes, pero no he visto mucha información sobre la comparación del rendimiento entre las dos opciones.

+0

Bueno, el JIT de PyPy puede producir un código bastante bueno para llamadas 'ctypes' desde una o dos versiones. Es posible que desee darle una oportunidad. No publico esto como respuesta porque no tengo datos disponibles y no está claro si cambiar de intérprete es una opción para ti. – delnan

+0

Espero que la sobrecarga sea similar. –

+0

@Delnan: Este es un juego que enviaré, también a Linux. No puedo pedirles a mis usuarios que instalen PyPy. – orlp

Respuesta

10

He comparado el rendimiento de una extensión C con una envoltura tipo ctypes. En mi prueba particular, la diferencia fue de aproximadamente 250x. Hubo varias llamadas a la biblioteca C por lo que el contenedor ctypes también estaba ejecutando el código Python. El tiempo de ejecución para la biblioteca C fue muy corto, lo que hizo que la sobrecarga adicional para el código Python fuera aún más significativa. Entonces la relación probablemente será diferente para ti pero fue significativa en mi caso.

+5

¿Cuál fue 250 veces más lenta? – delnan

+1

@delnan: de su respuesta puedo leer que el envoltorio de los tipos fue más lento. – orlp

6

La interfaz directamente codificada en C tiene el potencial de ser mucho más rápida. El cuello de botella es la interfaz de Python a C y los argumentos y resultados de clasificación pueden implicar, por ejemplo, copiar cadenas o convertir listas de Python a/desde matrices C. Si tiene un bucle que hace que cientos de estas llamadas y algunos de los datos no tengan que organizarse por separado para cada llamada, todo lo que tiene que hacer es recodificar el bucle en C y puede reducir masivamente el cuello de botella . ctypes no le da esa opción: todo lo que puede hacer es llamar directamente a las funciones existentes.

Por supuesto, todo depende exactamente de qué tipo de funciones está llamando y qué tipo de datos está pasando. Puede ser que no se puedan reducir los gastos generales, en cuyo caso yo esperaría que los ctypes sean más lentos pero quizás no significativamente.

Lo mejor que puede hacer es juntar alguna muestra de su código escrito en cada sentido y compararlo. De lo contrario, hay demasiadas variables para una respuesta definitiva.

+0

Los datos de los que estamos hablando son una máscara de bits (para colisión). Tengo una implementación C lista, y la única los datos que se pasan en el código de Python son booleanos, coordenadas y nuevas clases de máscara de bits de Python (que solo contienen un puntero a los datos reales, que viven en el código C). – orlp