像nodejs中的npm这样的cython项目管理
cython-npm的Python项目详细描述
像nodejs中的npm这样的cython项目管理。这个项目是受启发的 由Nodejs的NPM。
安装
您可以通过以下方式轻松安装:
pip install cython-npm
它能解决什么问题?
在使用cython时,我们面临编译cython文件的问题。我们能做到 很容易通过:
importpyximport;pyximport.install()
但不建议让{STR 1 } $ PyxPix构建代码 用户端作为钩住它们的导入系统。最好的迎合方式 对于最终用户来说,就是提供预先构建的二进制包。所以这个项目 编译.pyx文件并提供预构建的二进制包,以便 使用。
快速启动:
基本用于编译文件或文件夹
fromcython_npm.cythoncompileimportexportexport('examplefile.pyx')export('./examplefolder')# then import them to useimportexamplefilefromexamplefolderimport*
您应该只执行一次此代码。
创建安装文件,如package.json
您还可以同时编译许多文件或文件夹。创建文件 在项目/包的根目录中命名install.py,并编写 代码如下:
fromcython_npm.cythoncompileimportinstallManymodules=[# put your modules list here'examplefile.pyx','./examplefolder']install(Manymodules)
在开始项目之前运行文件
python install.py
或者在项目的启动文件中添加第一行import install。 在父文件夹中使用install或export将编译所有.pyx文件 子目录。###使用require('path')作为nodejs还可以 通过require函数在python中导入相对或完整路径。为了 示例:
fromcython_npm.cythoncompileimportrequire# import .pyx file. Will cause error if it is not compiled by export() yet.# Default value of recompile is True, only apply for .py file. To import .pyx, change recompile=Falseexamplefile=require('../parentpackage',recompile=False)# import cython package from parent folderexamplefile.somefunction()# it also support relative import .py fileexamplefile=require('../parentpackage')examplefile.somefunction()
使用requirepyx('path'):requirepyx与^{tt3}类似$ 除外:*仅用于cython文件('.pyx')*等同于 导出('.pyx file')并要求('.pyx file')示例:
fromcython_npm.cythoncompileimportexportexport('examplefile')require('examplefile',recompile=False)# The code above is the same as:fromcython_npm.cythoncompileimportrequirepyxrequirepyx('examplefile')
使用类型检查
另一个实用程序是typecheck,它支持在输入模块(从 Python3.3):
fromcython_npm.typecheckimporttypecheck@type_checkdefcheckstr(s:Any)->(None,str):returnNone,sx,y=checkstr('tuan')print(x,y)try:checkstr(120)exceptExceptionaserror:print(error)traceback.print_exc()# That will raise an error of TypeErrorcheckstr(200)
示例:cython vs speed test battle
这个例子比较了cython与python、swift、go和 做一个简短计算的代码差异。cython_npm用于 测试。这个测试是从“marcinkliks”派生的,原始代码和 测试在这里:Swift vs Go vs Python battle。注: 我们使用swift-and-go测试结果作为模式,不重新测试它们。去 在github的test文件夹中查看更多示例
测试条件:*python版本:python 3.6.3::anaconda,inc.
- 关于电脑:MacBook Pro(13英寸,2016,两个Thunderbolt 3端口) 2 GHz Intel Core i5,256GB固态硬盘
试验过程及结果如下:
回忆一下斯威夫特的速度:0米0.416秒,快走:0米0.592秒,皮比:0米2.633秒
测试纯python代码:
sum=0foreinrange(30):sum=0x=[]foriinrange(1000000):x.append(i)y=[]foriinrange(1000000-1):y.append(x[i]+x[i+1])i=0foriinrange(0,1000000,100):sum+=y[i]print(sum)
速度测试结果与原始测试相同/相似
time python test_python.py 9999010000 real 0m12.825s user 0m11.721s sys 0m1.061s
测试cython代码:创建run.py,代码:
fromcython_npm.cythoncompileimportexportexport('test_cython.pyx')# will do once timeimporttest_cython
在test_cython.pyx中编码:
cdeflongsum=0cdefinticdefinteforeinrange(30):sum=0x=[]foriinrange(1000000):x.append(i)y=[]foriinrange(1000000-1):y.append(x[i]+x[i+1])i=0foriinrange(0,1000000,100):sum+=y[i]print(sum)
速度测试结果:time python run.py
time python run.py 9999010000 real 0m5.803s user 0m4.496s sys 0m1.211s
使用列表优化和缓存测试cython代码:创建类似的 快跑。在test_cythoncache.pyx中编码:
fromfunctoolsimportlru_cache@lru_cache(maxsize=128)defdotest():cdeflongmysum=0cdefinticdefinteforeinrange(30):mysum=0x=[iforiinrange(1000000)]y=[x[i]+x[i+1]foriinrange(1000000-1)]i=0foriinrange(0,1000000,100):mysum+=y[i]print(mysum)dotest()
速度测试结果:
time python run.py 9999010000 real 0m3.373s user 0m2.360s sys 0m1.001s
使用cache和c数组测试cython代码:创建类似的run.py。代码 在test_cythoncache.pyx中:
fromfunctoolsimportlru_cache@lru_cache(maxsize=128)defdotest():cdeflongmysum=0cdefinticdefintecdefintx[1000000]cdefinty[1000000]foreinrange(30):mysum=0foriinrange(1000000):x[i]=i# y = []foriinrange(1000000-1):y[i]=(x[i]+x[i+1])i=0foriinrange(0,1000000,100):mysum+=y[i]print(mysum)dotest()
速度测试结果:
time python run.py 9999010000 real 0m0.085s user 0m0.067s sys 0m0.015s
结论
- 稍加改动,cython使纯python代码的速度提高了2倍。 但与swift and go相比,速度非常慢
- cython应用了一些最佳技术,使python的时间接近4倍 比原始代码快。这可能是可以接受的结果。侏儒 结果似乎也很吸引人。
- 使用c数组,cython使代码变得非常快。它消耗 只需0.085秒即可完成,比斯威夫特快4倍,比斯威夫特快6倍 去吧。它可能是最快的,但在现实生活中是不可用的。
- 毕竟,我希望cython和cython_npm能给你更多的帮助 编码选项