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.142scodon build可执行文件和刚才codon run总时间差不多,二进制文件执行时间也和codon run中的time计时几乎一样。
- 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安装完后,用如下脚本测试。
importcodonfromtimeimporttimedefis_prime_python(n):ifn<=1:returnFalseforiinrange(2,n):ifn%i==0:returnFalsereturnTrue@codon.jitdefis_prime_codon(n):ifn<=1:returnFalseforiinrange(2,n):ifn%i==0:returnFalsereturnTruet0=time()ans=sum(1foriinrange(100000,200000)ifis_prime_python(i))t1=time()print(f'[python]{ans}| took{t1-t0}seconds')t0=time()ans=sum(1foriinrange(100000,200000)ifis_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