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
相关推荐
weixin_440784114 小时前
【HandlerThread实现原理】
android·java·开发语言
天空'之城4 小时前
C 语言工业级通用组件手写 24:互补滤波
c语言·开发语言·互补滤波·嵌入式算法·工业级组件
XR1234567884 小时前
工厂车间无线网络方案对比:AGV漫游哪家强?
开发语言·php
傻啦嘿哟5 小时前
某短视频平台视频爬虫实战:抓取推荐流视频信息,绕过反爬的3种技巧
开发语言·爬虫·python
迷迭香yy5 小时前
集合竞价数据挖掘实战:用Python构建开盘信号识别系统
人工智能·python·数据挖掘
現実君5 小时前
【硬件进阶】AD22上位替换JLEDA教程
开发语言·php
mubei-1236 小时前
SpringDAO的用法
java·开发语言·数据库
李昊哲小课8 小时前
fastapi sse websocket 奶茶店实时订单看板
人工智能·python·websocket·网络协议·fastapi·sse
格林威8 小时前
多相机微秒级对齐:硬件触发 vs PTP(IEEE 1588)方案实战对比
开发语言·人工智能·数码相机·机器学习·计算机视觉·视觉检测·机器视觉
初级代码游戏9 小时前
iOS开发 Swift 速记2:三种集合类型 Array Set Dictionary
开发语言·ios·swift