El otro día encontré una biblioteca interesante de la que no había oído hablar antes.
PythoC es un compilador de lenguaje específico de dominio (DSL) que permite a los desarrolladores escribir programas en C utilizando la sintaxis estándar de Python. Toma un subconjunto de código Python tipado estáticamente y lo compila directamente en código de máquina nativo a través de LLVM IR (representación intermedia de máquina virtual de bajo nivel).
LLVM IR es un formato de código independiente de la plataforma utilizado internamente por el marco del compilador LLVM. Los compiladores primero traducen el código fuente a LLVM IR y luego LLVM convierte ese IR en código de máquina optimizado para CPU específicas (x86, ARM, etc.).
Una filosofía de diseño central de PythoC es: tiempo de ejecución equivalente a C + tiempo de compilación impulsado por Python, y tiene los siguientes puntos de venta casi únicos.
1. Crea ejecutables nativos independientes
A diferencia de herramientas como Cython, que se utilizan principalmente para crear extensiones C para acelerar los scripts de Python existentes, PythoC puede generar ejecutables de estilo C completamente independientes y autónomos. Una vez compilado, el binario resultante no requiere la ejecución del intérprete de Python ni de un recolector de basura.
2. Tiene control de bajo nivel con sintaxis de Python
PythoC refleja las capacidades de C pero las incluye en la sintaxis más limpia de Python. Para lograr esto, utiliza sugerencias de tipos nativos de la máquina en lugar de los tipos dinámicos estándar de Python.
Primitivas: i32, i8, f64, etc. Estructuras de memoria: Punteros (ptr[T]), matrices (matriz[T, N]) y estructuras (creadas decorando clases estándar de Python). Administración de memoria manual: debido a que no utiliza un recolector de basura de manera predeterminada, la administración de memoria es explícita, al igual que en C. Sin embargo, ofrece controles de seguridad modernos y opcionales, como tipos lineales (que garantizan que cada asignación se desasigne explícitamente para evitar fugas) y tipos de refinamiento (para aplicar controles de validación en tiempo de compilación).
Python como motor de metaprogramación
Una de las características más poderosas de PythoC es su manejo del paso de compilación. Debido a que el entorno de tiempo de compilación es solo Python, puede usar la lógica estándar de Python para generar, manipular y especializar su código PythoC antes de compilarlo en LLVM. Esto le brinda capacidades de generación de código en tiempo de compilación altamente flexibles (similares a las plantillas de C++ pero impulsadas por Python puro).
Suena prometedor, pero ¿la realidad está a la altura de las expectativas? Bien, veamos esta biblioteca en acción. Instalarlo es fácil, como la mayoría de las bibliotecas de Python, es solo una instalación pip como esta:
instalación de pip en pythoc
Pero probablemente sea mejor configurar un entorno de desarrollo adecuado donde pueda aislar sus diferentes proyectos. En mi ejemplo, estoy usando la utilidad UV, pero uso el método con el que te sientas más cómodo. Escriba los siguientes comandos en su terminal de línea de comandos.
C:\Users\thoma\projects> cd proyectos C:\Users\thoma\projects> uv init pythoc_test C:\Users\thoma\projects> cd pythoc_test C:\Users\thoma\projects\pythoc_test> uv venv –python 3.12 C:\Users\thoma\projects\pythoc_test> .venv\Scripts\activate (pythoc_test) C:\Users\thoma\projects\pythoc_test> uv pip instalar pythoc
Un ejemplo sencillo
Para usar PythoC, debe definir funciones usando tipos de máquinas específicos y marcarlas con el decorador de compilación de PythoC. Hay dos formas principales de ejecutar su código PythoC. Puedes llamar a la biblioteca compilada directamente desde Python de esta manera,
desde pythoc import compilar, i32 @compile def add(x: i32, y: i32) -> i32: return x + y # Puede compilar en código nativo @compile def main() -> i32: return add(10, 20) # Llamar a la biblioteca dinámica compilada desde Python directamente result = main() print(resultado)
Luego ejecútelo así.
(pythoc_test) C:\Users\thoma\projects\pythoc_test>python test1.py 30
O puede crear un ejecutable independiente que pueda ejecutar independientemente de Python. Para hacer eso, use un código como este.
desde pythoc import compile, i32 @compile def add(x: i32, y: i32) -> i32: print(x + y) return x + y # Puede compilar en código nativo @compile def main() -> i32: return add(10, 20) if __name__ == “__main__”: from pythoc import compile_to_executable compile_to_executable()
Lo ejecutamos de la misma manera.
(pythoc_test) C:\Users\thoma\projects\pythoc_test>python test4.py Compilado exitosamente en ejecutable: build\test4.exe 1 archivo(s) de objeto vinculados
Esta vez, no vemos ningún resultado. En cambio, PythoC crea un directorio de compilación debajo de su directorio actual y luego crea allí un archivo ejecutable que puede ejecutar.
(pythoc_test) C:\Users\thoma\projects\pythoc_test>dir build\test4* El volumen en la unidad C es el número de serie del volumen de Windows es EEB4-E9CA Directorio de C:\Users\thoma\projects\pythoc_test\build 26/02/2026 14:32 297 test4.deps 26/02/2026 14:32 168,448 test4.exe 26/02/2026 14:32 633 test4.ll 26/02/2026 14:32 412 test4.o 26/02/2026 14:32 0 test4.o.lock 26/02/2026 14:32 1.105.920 prueba4.pdb
Podemos ejecutar el archivo test4.exe tal como lo haríamos con cualquier otro ejecutable.
(pythoc_test) C:\Users\thoma\projects\pythoc_test>build\test4.exe (pythoc_test) C:\Users\thoma\projects\pythoc_test>
Pero espera un segundo. En nuestro código Python, solicitamos explícitamente imprimir el resultado de la suma, pero no vemos ningún resultado. ¿Qué está sucediendo?
La respuesta es que la función print() incorporada de Python se basa en el intérprete de Python que se ejecuta en segundo plano para descubrir cómo mostrar los objetos. Debido a que PythoC elimina todo eso para construir un ejecutable nativo diminuto e increíblemente rápido, la declaración de impresión se elimina.
Para imprimir en la pantalla en un binario nativo, debe usar la función estándar de la biblioteca C: printf.
Cómo usar printf en PythoC
En C (y por lo tanto en PythoC), la impresión de variables requiere especificadores de formato. Escribe una cadena con un marcador de posición (como %d para un entero decimal) y luego pasa la variable que desea insertar en ese marcador de posición.
Así es como actualiza nuestro código para importar la función C printf y usarla correctamente:
de pythoc import compile, i32, ptr, i8, extern # 1. Dígale a PythoC que se vincule a la función printf estándar de C @extern def printf(fmt: ptr[i8]*args) -> i32: pasar @compile def add(x: i32, y: i32) -> i32: printf(“Sumando 10 y 20 = %d\n”, x+y) return x + y @compile def main() -> i32: resultado = add(10, 20) # 2. Utilice printf con una cadena de formato estilo C. # %d es el marcador de posición para nuestro número entero (resultado). # \n agrega una nueva línea al final. devolver 0 si __name__ == “__main__”: de pythoc importar compila_to_executable compilar_to_executable()
Ahora, si volvemos a ejecutar el código anterior y ejecutamos el ejecutable resultante, nuestro resultado será el que esperábamos.
(pythoc_test) C:\Users\thoma\projects\pythoc_test>python test5.py Compilado exitosamente en ejecutable: build\test5.exe Vinculado 1 archivo(s) objeto (pythoc_test) C:\Users\thoma\projects\pythoc_test>build\test5.exe Sumando 10 y 20 = 30
¿Pero realmente vale la pena molestarse?
Todo lo que hemos hablado sólo valdrá la pena si vemos mejoras reales de velocidad en nuestro código. Entonces, para nuestro ejemplo final, veamos qué tan rápido se pueden comparar nuestros programas compilados con su equivalente en Python, y eso debería responder nuestra pregunta definitivamente.
Primero, el código Python normal. Usaremos un cálculo recursivo de Fibonacci para simular un proceso de larga duración. Calculemos el cuadragésimo número de Fibonacci.
import time def fib(n): # Esto calcula la secuencia de forma recursiva si n <= 1: return n return fib(n - 1) + fib(n - 2) if __name__ == "__main__": print("Iniciando la prueba de velocidad estándar de Python...") start_time = time.time() # fib(38) normalmente tarda alrededor de 10 segundos en Python, # dependiendo de la CPU de tu computadora. resultado = fib(40) tiempo_final = tiempo.tiempo() print(f"Resultado: {resultado}") print(f"Tiempo empleado: {tiempo_final - tiempo_inicio:.4f} segundos")
Obtuve este resultado al ejecutar el código anterior.
(pythoc_test) C:\Users\thoma\projects\pythoc_test>python test6.py Iniciando la prueba de velocidad estándar de Python… Resultado: 102334155 Tiempo necesario: 15,1611 segundos
Ahora veamos el código basado en PythoC. Nuevamente, al igual que con la declaración de impresión en nuestro ejemplo anterior, no podemos simplemente usar la directiva de temporización de importación normal de Python para nuestros tiempos. En su lugar, tenemos que tomar prestada la función de temporización estándar directamente del lenguaje de programación C: clock(). Definimos esto de la misma manera que la declaración printf que usamos anteriormente.
Aquí está el script PythoC actualizado con el temporizador C integrado.
desde pythoc import compile, i32, ptr, i8, extern # 1. Importe C’s printf @extern def printf(fmt: ptr[i8]*args) -> i32: pase # 2. Importar la función de reloj de C @extern def clock() -> i32: pase @compile def fib(n: i32) -> i32: if n <= 1: return n return fib(n - 1) + fib(n - 2) @compile def main() -> i32: printf(“Iniciando la prueba de velocidad de PythoC…\n”) # Obtener la hora de inicio (esto cuenta en “tics”) start_time = clock() # Ejecutar el cálculo pesado result = fib(40) # Obtener la hora de finalización end_time = clock() # Calcular la diferencia. # Nota: En Windows, 1 tic del reloj = 1 milisegundo. elapsed_ms = end_time – start_time printf(“Resultado: %d\n”, resultado) printf(“Tiempo necesario: %d milisegundos\n”, elapsed_ms) devuelve 0 si __name__ == “__main__”: de pythoc import compile_to_executable compile_to_executable()
Mi resultado esta vez fue,
(pythoc_test) C:\Users\thoma\projects\pythoc_test>python test7.py Compilado exitosamente en ejecutable: build\test7.exe Vinculado 1 archivo(s) de objeto (pythoc_test) C:\Users\thoma\projects\pythoc_test>build\test7.exe Iniciando la prueba de velocidad de PythoC… Resultado: 102334155 Tiempo necesario: 308 milisegundos
Y en este pequeño ejemplo, aunque el código es un poco más complejo, vemos la ventaja real de usar lenguajes compilados como C. Nuestro ejecutable era 40 veces más rápido que el código Python equivalente. No está nada mal.
¿Para quién es PythoC?
Veo tres tipos principales de usuarios de PythoC.
1/ Como vimos en nuestra prueba de velocidad de Fibonacci, Python estándar puede ser lento cuando se realizan trabajos matemáticos pesados. PythoC podría ser útil para cualquier desarrollador de Python que cree simulaciones físicas, algoritmos complejos o procesos de procesamiento de datos personalizados y que se haya topado con un muro de rendimiento.
2/ Los programadores que trabajan estrechamente con el hardware de la computadora (como construir motores de juegos, escribir controladores o programar pequeños dispositivos IoT) generalmente escriben en C porque necesitan administrar la memoria de la computadora manualmente.
PythoC podría atraer a estos desarrolladores porque ofrece el mismo control de memoria manual (usando punteros y tipos nativos), pero les permite usar Python como un motor de “metaprogramación” para escribir código más limpio y flexible antes de compilarlo al nivel de hardware.
3/ Si escribe un script de Python útil y desea compartirlo con un compañero de trabajo, ese compañero de trabajo generalmente necesita instalar Python, configurar un entorno virtual y descargar sus dependencias. Puede ser una molestia, especialmente si el usuario objetivo no tiene muchos conocimientos de TI. Sin embargo, con PythoC, una vez que tenga su ejecutable C compilado, cualquiera puede ejecutarlo simplemente haciendo doble clic en el archivo.
¿Y para quién no es?
La otra cara de lo anterior es que PythoC probablemente no sea la mejor herramienta para un desarrollador web, ya que los cuellos de botella en el rendimiento generalmente se deben a las velocidades de la red o de la base de datos, no a las velocidades de cálculo de la CPU.
Asimismo, si ya eres usuario de bibliotecas optimizadas como NumPy, tampoco verás muchos beneficios.
Resumen
Este artículo le presentó la biblioteca PythoC relativamente nueva y desconocida. Con él, puedes usar Python para crear código ejecutable C independiente y súper rápido.
Di varios ejemplos del uso de Python y la biblioteca PythoC para producir programas ejecutables en C, incluido uno que mostró una velocidad increíble al ejecutar el ejecutable producido por la biblioteca PythoC en comparación con un programa Python estándar.
Un problema con el que se encontrará es que las importaciones de Python no son compatibles con los programas PythoC, pero también mostré cómo solucionarlo reemplazándolos con funciones integradas de C equivalentes.
Finalmente, hablé sobre quiénes pensaba que eran los tipos de programadores de Python que podrían ver un beneficio en el uso de PythonC en sus cargas de trabajo y aquellos que no.
Espero que esto haya despertado su apetito por ver para qué tipos de casos de uso puede aprovechar PythoC. Puede obtener mucho más información sobre esta útil biblioteca consultando el repositorio de GitHub en el siguiente enlace.
https://github.com/1flei/PythoC