JIT执行python脚本的工具codon安装和测试

1.下载codon预编译二进制文件

因为codon尚不支持windows操作系统,所以下载Linux版本。

复制代码
C:\d>curl -LO https://github.com/exaloop/codon/releases/download/v0.19.6/codon-linux-x86_64.tar.gz -C -

登录wsl

复制代码
C:\d>wsl

root@DESKTOP-59T6U68:/mnt/c/d# export PATH=/mnt/c/d/codon-deploy-linux-x86_64/bin:$PATH
root@DESKTOP-59T6U68:/mnt/c/d# codon --version
0.19.6

因为codon不支持高版本python的f"string"语法,报错

复制代码
ValueError: invalid format specifier: locale::facet::_S_create_c_locale name not valid

Raised from: std.internal.format._format_error.0:0
/mnt/c/d/codon-deploy-linux-x86_64/lib/codon/stdlib/internal/format.codon:4:2

Backtrace:
  [0x7fab10ff4ed8] std.internal.format._format_error.0:0[str].1428 at /mnt/c/d/codon-deploy-linux-x86_64/lib/codon/stdlib/internal/format.codon:4:2
  [0x7fab10ff7ac8] str:str.__format__:0[str,str].1583 at /mnt/c/d/codon-deploy-linux-x86_64/lib/codon/stdlib/internal/format.codon:137:27
  [0x7fab10ffaf18] compare_algorithms.0:0[std.internal.types.array.List.0[int]].1853 at /mnt/c/d/comp_prime1.py:95:11
  [0x7fab10ffe5c9] main.0 at /mnt/c/d/comp_prime1.py:153:24

所以把comp_prime1.py测试程序中的

复制代码
        print(f"{limit:<12,} {'埃拉托斯特尼筛法':<20} {count_era:<12,} {sum_era:<20,} {time_era:<12.4f}")
        print(f"{limit:<12,} {'Atkin筛法':<20} {count_atkin:<12,} {sum_atkin:<20,} {time_atkin:<12.4f}")
        print(f"{'':<12} {'速度比(埃氏筛/Atkin)':<20} {'':<12} {'':<20} {time_era/time_atkin:<12.2f}x")

改为:

复制代码
        print("{:<12,} {:<20} {:<12,} {:<20,} {:<12.4f}".format(limit, '埃拉托斯特尼筛法', count_era, sum_era, time_era))
        print("{:<12,} {:<20} {:<12,} {:<20,} {:<12.4f}".format(limit, 'Atkin筛法', count_atkin, sum_atkin, time_atkin))
        print("{:<12} {:<20} {:<12} {:<20} {:<12.2f}x".format('', '速度比(埃氏筛/Atkin)', '', '', time_era/time_atkin))

仍然不支持,报错

复制代码
comp_prime1.py:126 (15-129): error: ''{:<12,} {:<20} {:<12,} {:<20,} {:<12.4f}'' object has no attribute 'format'
╰─ comp_prime1.py:153 (5-23): error: during the realization of compare_algorithms(limits: List[int])

最后改为:

复制代码
        print(limit, '埃拉托斯特尼筛法', count_era, sum_era, time_era)
        print(limit, 'Atkin筛法', count_atkin, sum_atkin, time_atkin)

分别用python、codon run、codon run --release执行, 结果如下

复制代码
root@DESKTOP-59T6U68:/mnt/c/d# python3 comp_prime1.py
✓ 验证通过:埃拉托斯特尼筛法和Atkin筛法结果一致

================================================================================
上限           算法                   素数个数         素数总和                 耗时(秒)
================================================================================
1000000 埃拉托斯特尼筛法 78498 37550402023 0.042834967998715
1000000 Atkin筛法 78498 37550402023 0.17276220399980957
5000000 埃拉托斯特尼筛法 348513 838596693108 0.2414542509995954
5000000 Atkin筛法 348513 838596693108 0.9579475489990728
10000000 埃拉托斯特尼筛法 664579 3203324994356 0.4767417179991753
10000000 Atkin筛法 664579 3203324994356 2.559093847999975

root@DESKTOP-59T6U68:/mnt/c/d# time codon run comp_prime1.py
✓ 验证通过:埃拉托斯特尼筛法和Atkin筛法结果一致

================================================================================
上限           算法                   素数个数         素数总和                 耗时(秒)
================================================================================
1000000 埃拉托斯特尼筛法 78498 37550402023 0.0315723
1000000 Atkin筛法 78498 37550402023 0.0174501
5000000 埃拉托斯特尼筛法 348513 838596693108 0.145239
5000000 Atkin筛法 348513 838596693108 0.075182
10000000 埃拉托斯特尼筛法 664579 3203324994356 0.276909
10000000 Atkin筛法 664579 3203324994356 0.161016

real    0m5.890s
user    0m3.474s
sys     0m0.924s

root@DESKTOP-59T6U68:/mnt/c/d# time codon run --release comp_prime1.py
✓ 验证通过:埃拉托斯特尼筛法和Atkin筛法结果一致

================================================================================
上限           算法                   素数个数         素数总和                 耗时(秒)
================================================================================
1000000 埃拉托斯特尼筛法 78498 37550402023 0.0182185
1000000 Atkin筛法 78498 37550402023 0.00952959
5000000 埃拉托斯特尼筛法 348513 838596693108 0.0525434
5000000 Atkin筛法 348513 838596693108 0.0277581
10000000 埃拉托斯特尼筛法 664579 3203324994356 0.0767064
10000000 Atkin筛法 664579 3203324994356 0.0701954

real    0m7.966s
user    0m3.416s
sys     0m0.709s

观察发现Atkin筛法在codon中速度比埃拉托斯特尼筛法快1倍,加--release还能快二倍,而在python中,Atkin筛法比埃拉托斯特尼筛法更慢。

还有,codon因为有编译过程,实际执行总时间更长。

再测试build成可执行文件

复制代码
root@DESKTOP-59T6U68:/mnt/c/d# time codon build --release comp_prime1.py
error: process for 'g++' exited with status 255

在目录下生成了comp_prime1.o,但是要有g++才能链接成可执行文件,只好进入gcc容器完成。

复制代码
root@DESKTOP-59T6U68:/mnt/c/d# docker start gcc
gcc
root@DESKTOP-59T6U68:/mnt/c/d# docker exec -it gcc bash
root@6ae32a5ffcde:/par# export PATH=/par/codon/bin:$PATH
root@6ae32a5ffcde:/par# time codon build -release -exe comp_prime1.py

real    0m5.883s
user    0m3.246s
sys     0m0.933s
root@6ae32a5ffcde:/par# ./comp_prime1
✓ 验证通过:埃拉托斯特尼筛法和Atkin筛法结果一致


================================================================================
上限           算法                   素数个数         素数总和                 耗时(秒)
================================================================================
1000000 埃拉托斯特尼筛法 78498 37550402023 0.0133491
1000000 Atkin筛法 78498 37550402023 0.00743747
5000000 埃拉托斯特尼筛法 348513 838596693108 0.0468318
5000000 Atkin筛法 348513 838596693108 0.0217066
10000000 埃拉托斯特尼筛法 664579 3203324994356 0.0686731
10000000 Atkin筛法 664579 3203324994356 0.04861

real    0m0.328s
user    0m1.218s
sys     0m0.142s

codon build可执行文件和刚才codon run总时间差不多,二进制文件执行时间也和codon run中的time计时几乎一样。

  1. codon_jit模块

codon还提供了在python中执行的codon_jit模块,但是这个模块的whl其实是源代码,安装过程还需要clang编译器,所以改到clang容器。

安装codon-jit还需要setuptools和numpy, 但它们不会作为依赖包自动下载,需要手工下载。

复制代码
C:\d>wsl
root@DESKTOP-59T6U68:/mnt/c/d# docker start clang
clang
root@DESKTOP-59T6U68:/mnt/c/d# docker exec -it clang bash
root@DESKTOP-59T6U68:/# cd /par
root@DESKTOP-59T6U68:/par# export PATH=/par/codon/bin:$PATH
root@DESKTOP-59T6U68:/par# cd tpy3145
root@DESKTOP-59T6U68:/par/tpy3145# python/bin/python -m venv myenv
root@DESKTOP-59T6U68:/par/tpy3145# source myenv/bin/activate
(myenv) root@DESKTOP-59T6U68:/par/tpy3145# pip download codon-jit setuptools -d 314 -i https://mirrors.aliyun.com/pypi/simple/
Looking in indexes: https://mirrors.aliyun.com/pypi/simple/
Collecting codon-jit
  Downloading codon_jit-0.4.6.tar.gz (6.4 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Collecting setuptools
  Using cached setuptools-82.0.1-py3-none-any.whl (1.0 MB)
Collecting cython (from codon-jit)
  Using cached cython-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (3.4 MB)
Collecting astunparse (from codon-jit)
  Downloading astunparse-1.6.3-py2.py3-none-any.whl (12 kB)
Collecting wheel<1.0,>=0.23.0 (from astunparse->codon-jit)
  Using cached wheel-0.47.0-py3-none-any.whl (32 kB)
Collecting six<2.0,>=1.6.1 (from astunparse->codon-jit)
  Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)
Collecting packaging>=24.0 (from wheel<1.0,>=0.23.0->astunparse->codon-jit)
  Using cached packaging-26.2-py3-none-any.whl (100 kB)
Saved ./314/codon_jit-0.4.6.tar.gz
Saved ./314/setuptools-82.0.1-py3-none-any.whl
Saved ./314/astunparse-1.6.3-py2.py3-none-any.whl
Saved ./314/six-1.17.0-py2.py3-none-any.whl
Saved ./314/wheel-0.47.0-py3-none-any.whl
Saved ./314/packaging-26.2-py3-none-any.whl
Saved ./314/cython-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Successfully downloaded codon-jit setuptools astunparse six wheel packaging cython

[notice] A new release of pip is available: 26.1 -> 26.1.1
[notice] To update, run: pip install --upgrade pip


(myenv) root@DESKTOP-59T6U68:/par/tpy3145# pip install codon-jit setuptools -f 314 --no-index
Looking in links: 314
Processing ./314/codon_jit-0.4.6.tar.gz
  Installing build dependencies ... error
  error: subprocess-exited-with-error

  × installing build dependencies for codon-jit did not run successfully.
  │ exit code: 1
  ╰─> [6 lines of output]
      Looking in links: 314
      Processing ./314/cython-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
      Processing ./314/setuptools-82.0.1-py3-none-any.whl
      Processing ./314/wheel-0.47.0-py3-none-any.whl
      ERROR: Could not find a version that satisfies the requirement numpy (from versions: none)
      ERROR: No matching distribution found for numpy
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed to build 'codon-jit' when installing build dependencies for codon-jit
(myenv) root@DESKTOP-59T6U68:/par/tpy3145# pip download numpy -d 314 -i https://mirrors.aliyun.com/pypi/simple/
Looking in indexes: https://mirrors.aliyun.com/pypi/simple/
Collecting numpy
  Using cached numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (16.6 MB)
Saved ./314/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Successfully downloaded numpy

[notice] A new release of pip is available: 26.1 -> 26.1.1
[notice] To update, run: pip install --upgrade pip
(myenv) root@DESKTOP-59T6U68:/par/tpy3145# pip install numpy codon-jit setuptools -f 314 --no-index
Looking in links: 314
Processing ./314/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Processing ./314/codon_jit-0.4.6.tar.gz
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Processing ./314/setuptools-82.0.1-py3-none-any.whl
Processing ./314/cython-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (from codon-jit)
Processing ./314/astunparse-1.6.3-py2.py3-none-any.whl (from codon-jit)
Processing ./314/wheel-0.47.0-py3-none-any.whl (from astunparse->codon-jit)
Processing ./314/six-1.17.0-py2.py3-none-any.whl (from astunparse->codon-jit)
Processing ./314/packaging-26.2-py3-none-any.whl (from wheel<1.0,>=0.23.0->astunparse->codon-jit)
Building wheels for collected packages: codon-jit
  Building wheel for codon-jit (pyproject.toml) ... done
  Created wheel for codon-jit: filename=codon_jit-0.4.6-cp314-cp314-linux_x86_64.whl size=111005 sha256=b55a5588932fdff64766d282dd927fb5d137b4f58e82efc4a58af78a28280615
  Stored in directory: /root/.cache/pip/wheels/1a/91/bf/9019ca535cbd306b4e347cb15bc1ee391c2907bd39b1d747b3
Successfully built codon-jit
Installing collected packages: six, setuptools, packaging, numpy, cython, wheel, astunparse, codon-jit
Successfully installed astunparse-1.6.3 codon-jit-0.4.6 cython-3.2.4 numpy-2.4.4 packaging-26.2 setuptools-82.0.1 six-1.17.0 wheel-0.47.0

安装完后,用如下脚本测试。

python 复制代码
import codon
from time import time

def is_prime_python(n):
    if n <= 1:
        return False
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

@codon.jit
def is_prime_codon(n):
    if n <= 1:
        return False
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

t0 = time()
ans = sum(1 for i in range(100000, 200000) if is_prime_python(i))
t1 = time()
print(f'[python] {ans} | took {t1 - t0} seconds')

t0 = time()
ans = sum(1 for i in range(100000, 200000) if is_prime_codon(i))
t1 = time()
print(f'[codon]  {ans} | took {t1 - t0} seconds')

可见,is_prime_python和is_prime_codon代码完全一样,只是后者前面加了一行@codon.jit装饰器。

执行结果如下:

复制代码
(myenv) root@DESKTOP-59T6U68:/par/tpy3145# python /par/test-codonjit.py
[python] 8392 | took 27.18236517906189 seconds
[codon]  8392 | took 2.758159637451172 seconds

@codon.jit装饰器即时编译的语句执行时间只有原始语句的十分之一。和直接用codon二进制文件执行比较,还是codon略快

复制代码
(myenv) root@DESKTOP-59T6U68:/par/tpy3145# codon run /par/test-codon.py
[python] 8392 | took 1.50474 seconds
(myenv) root@DESKTOP-59T6U68:/par/tpy3145# codon run --release /par/test-codon.py
[python] 8392 | took 1.47974 seconds


(myenv) root@DESKTOP-59T6U68:/par/tpy3145# time codon run /par/test-codon.py
[python] 8392 | took 1.41773 seconds

real    0m6.960s
user    0m4.180s
sys     0m0.744s
(myenv) root@DESKTOP-59T6U68:/par/tpy3145# time codon run --release /par/test-codon.py
[python] 8392 | took 1.5051 seconds

real    0m8.147s
user    0m4.022s
sys     0m0.694s

想到clang本身也自带c++编译器,测试build还是不行。

复制代码
(myenv) root@DESKTOP-59T6U68:/par/tpy3145# time codon build --release /par/test-codon.py
/usr/bin/ld: cannot find -lz: No such file or directory
g++: error: linker command failed with exit code 1 (use -v to see invocation)
error: process for 'g++' exited with status 1

real    0m5.700s
user    0m2.523s
sys     0m0.755s
相关推荐
zzzzzz3102 小时前
当产品经理说这个很简单:我用Python自动化处理奇葩需求的实战指南
python·pycharm·产品经理
雪隐2 小时前
个人电脑玩AI-06让5060 Ti给你打工——不光能画画,Qwen3-TTS还能学人说话,连我老板都信了!
人工智能·后端·python
兵慌码乱14 小时前
面向桌面端的资产管理系统分层架构设计与核心模块实现
python·系统架构·sqlite·pyqt5·数据库设计·桌面应用开发·mvc架构
hboot15 小时前
AI工程师第三课 - 机器学习基础
python·scikit-learn·kaggle
顾林海20 小时前
Agent入门阶段-编程基础-Python:流程控制
python·agent·ai编程
呱呱复呱呱1 天前
Django CBV 源码解读:一个请求是怎么找到你的 get() 方法的
python·django
曲幽1 天前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
荣码1 天前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
兵慌码乱2 天前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理
金銀銅鐵2 天前
[Python] 体验用欧几里得算法计算最大公约数的过程
python·数学