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
相关推荐
程似锦吖1 小时前
无中生有 之 从0开始写一个动态定时任务管理
java·开发语言
2501_901006472 小时前
Golang怎么用gRPC Gateway_Golang gRPC Gateway教程【经典】
jvm·数据库·python
2501_901200532 小时前
golang如何实现错误预算Error Budget计算_golang错误预算Error Budget计算实现实战
jvm·数据库·python
2401_867623982 小时前
如何解决OUI图形界面无法调用_xhost与DISPLAY变量设置
jvm·数据库·python
Dxy12393102162 小时前
Python 去除 HTML 标签获取纯文本
开发语言·python·html
2401_824697662 小时前
CSS如何实现元素反转特效_使用transform-scaleX(-1)操作
jvm·数据库·python
CLX05052 小时前
如何在 WordPress AMP 网站中为特定模板禁用 AMP 渲染
jvm·数据库·python
砚底藏山河2 小时前
python、JavaScript 、JAVA,定制化数据服务,助力业务高效落地
java·javascript·python
神明9312 小时前
如何实现SQL动态字段选择查询_利用反射或动态拼接字符串
jvm·数据库·python