Codon: 又一个Python编译器,尝鲜与速览
Python作为脚本语言,学习曲线平缓,各种包、库足够方便,使用者众多,但是性能一直是个大问题(虽然严格来说,当触摸到Python极限的时候,大概率有能力换其他语言/寻求其他解决方案)。为了解决性能问题, exaloop推出了基于LLVM的Python编译器,即由Cpython的interpreter
变成了Codon的compiler
,详情可参考Github仓库。
安装
环境:Debian 11 amd64, Python 3.9, root用户
首先安装Codon环境
/bin/bash -c "$(curl -fsSL https://exaloop.io/install.sh)"
安装完成后,输入codon
查看是否配置好了,如下即可:
error: Available commands: codon <run|build|doc>
如果报错找不到codon,需要手动配置/root/.bashrc
,添加export PATH=/root/.codon/bin:$PATH
并source /root/.bashrc
激活。
环境修改
Codon默认的Python库是libpython.so
,但是Debian使用的是具体的名字,如libpython.3.9.so
,所以在编译的时候会报错找不到依赖库,执行以下命令(注意Python版本),软链接一个即可:
ln -s /usr/lib/x86_64-linux-gnu/libpython3.9.so /usr/lib/x86_64-linux-gnu/libpython.so
实际测试
Codon目前还处于极其原始的状态,比如不支持unicode只能使用ASCII,Python package支持度不足等问题。但是瑕不掩瑜,先测试一下实际使用的程序,而不是官方的benchmark内容,不然就成安兔兔优化跑分了。
具体的程序在页尾,使用如下编译程序:
codon build -exe -release CheckSysUpgradable.py
可以看到程序中出现了from python import xxx
的内容,这是因为很多package是不被codon支持的(可以粗略的理解为不兼容),所以‘借用’了Python的功能。此外,在 num = output.count("upgradable")
之前还出现了num = 0
,这个不常用的初始化是为了符合LLVM的要求,所以Codon也不是那么的Python了。
总结
性能上,比CPython很多,毕竟是优化编译的程序,不是解释器这类能比的。
兼容性上,Codon之于Python,更像是carbon之于c++,已有的Python程序用Codon编译,需要修改的地方不少。
总体而言,Codon更像是借用了Python风格的新语言,从官网上演示的程序后缀是.codon
而不是.py
就能看出来一二。
总之,要是有个Python风格的Golang,那就完美了
测试程序
from python import os
import time
from python import telebot
# sned message to telegram bot
def send_message(message):
bot = telebot.TeleBot("123456789:XXXXXXXXX-XXXXXXXXXXXXX")
bot.send_message(123456789, message)
# execute command "apt list --upgradable" and get output, return output
def get_output():
# execute command "apt update" silently
os.system("apt update > /dev/null")
time.sleep(1)
output = os.popen("apt list --upgradable").read()
# find the number of packages to be updated
num = 0
num = output.count("upgradable")
#print(num)
# return number of packages to be updated
return num
# main function
def main():
# get number of packages to be updated
num = get_output()
# if number of packages to be updated is not 0, send message to telegram bot
if num != 0:
send_message(str(num) + " packages to be updated.")
if __name__ == "__main__":
main()