zoukankan      html  css  js  c++  java
  • cpython的使用

    这个的学习主要是因为在运行目标检测的代码时总是会出现下面的错误:

            from Cython.Build import cythonize
        ModuleNotFoundError: No module named 'Cython'
        ----------------------------------------
    ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

    安装:

    pip install Cython
    Collecting Cython
      Downloading Cython-0.29.19-cp37-cp37m-macosx_10_9_x86_64.whl (1.9 MB)

    所以打算学学这个模块是怎么用的,以及用在哪里的

    https://github.com/Sean16SYSU/CPython-Tutorial-zh

    Python有时候太慢,如果手动编译C或者是C++来写#include<Python.h>的文件也比较麻烦。 CPython无疑是一个比较好的选择。

    改进的理由

    1. 每一行的计算量很少,因此python解释器的开销就会变的很重要。
    2. 数据的局部性原理:很可能是,当使用C的时候,更多的数据可以塞进CPU的cache中,因为Python的元素都是Object,而每个Object都是通过字典实现的,cache对这个数据不很友好。

    项目

    Hello World项目

    第一个项目是Hello world。

    创建一个文件helloworld.pyx,内容如下:

    print("Hello world!")

    保存后,创建setup.py文件,内容如下:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules = cythonize("helloworld.pyx")
    )

    保存后,命令行进入setup.py所在目录,并输入python setup.py build_ext --inplace,如下:

    $python setup.py build_ext --inplace
    Compiling helloworld.pyx because it changed.
    [1/1] Cythonizing helloworld.pyx
    /anaconda3/envs/deeplearning/lib/python3.7/site-packages/Cython/Compiler/Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /Users/user/pytorch/NLP学习/learning_2.0/helloworld.pyx
      tree = Parsing.p_module(s, pxd, full_module_name)
    running build_ext
    building 'helloworld' extension
    creating build
    creating build/temp.macosx-10.9-x86_64-3.7
    gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/anaconda3/envs/deeplearning/include -arch x86_64 -I/anaconda3/envs/deeplearning/include -arch x86_64 -I/anaconda3/envs/deeplearning/include/python3.7m -c helloworld.c -o build/temp.macosx-10.9-x86_64-3.7/helloworld.o
    gcc -bundle -undefined dynamic_lookup -L/anaconda3/envs/deeplearning/lib -arch x86_64 -L/anaconda3/envs/deeplearning/lib -arch x86_64 -arch x86_64 build/temp.macosx-10.9-x86_64-3.7/helloworld.o -o /Users/user/pytorch/NLP学习/learning_2.0/helloworld.cpython-37m-darwin.so

    运行完这个命令后,该目录下就会生成三个文件:

    build                    helloworld.pyx
    helloworld.c                setup.py
    helloworld.cpython-37m-darwin.so

    然后创建一个调用文件test.py,内容为:

    import helloworld

    运行返回:

    i$ python test.py 
    Hello world!

    .pyx文件:

    pyx文件是python的c扩展文件,代码要符合cython的规范,用什么编辑器写都行。我在eric4上写的,结果它默认用python解释器来进行解释,还提示有bug,“语法错误”。

    上面的pyx文件还仅仅是源代码文件,要想被python调用、要想运行,仅仅写了源代码还是不够的(不像 Python 语言可直接解释使用的 .py 文件,.pyx 文件必须先被编译成 .c 文件,再编译成 .pyd (Windows 平台) 或 .so (Linux 平台) 文件,才可作为模块 import 导入使用)。具体来说,还要转成.c或者.c++的文件,并且再进一步转成.pyd文件。pyd文件才是可以直接使用的文件。为了达到上述目的,就要写一个setup.py脚本,如上面那种

    上述两个步骤,相当于把某个python效率瓶颈模块(这之前需要用profile工具来定位)用效率更高的代码写成了python的c扩展形式,接下来,就是要在python代码中调用他们。test.py就是这个调用的脚本

    Fibonacci Function项目

    斐波那契数列:1, 1, 2, 3, 5,... 前两位为1,之后每个数等于前面两个数之和。

    创建fib.pyx,内容如下:

    from __future__ import print_function
    
    def fib(n):
        a, b = 0, 1
        while b < n:
            print(b, end=' ')
            a, b = b, a+b
        print()

    创建setup.py文件,内容如下:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules = cythonize("fib.pyx")
    )

    通过命令python setup.py build_ext --inplace,生成出来的文件:

    python setup.py build_ext --inplace
    Compiling fib.pyx because it changed.
    [1/1] Cythonizing fib.pyx
    /anaconda3/envs/deeplearning/lib/python3.7/site-packages/Cython/Compiler/Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /Users/user/pytorch/NLP学习/learning_2.0/fib.pyx
      tree = Parsing.p_module(s, pxd, full_module_name)
    running build_ext
    building 'fib' extension
    gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/anaconda3/envs/deeplearning/include -arch x86_64 -I/anaconda3/envs/deeplearning/include -arch x86_64 -I/anaconda3/envs/deeplearning/include/python3.7m -c fib.c -o build/temp.macosx-10.9-x86_64-3.7/fib.o
    gcc -bundle -undefined dynamic_lookup -L/anaconda3/envs/deeplearning/lib -arch x86_64 -L/anaconda3/envs/deeplearning/lib -arch x86_64 -arch x86_64 build/temp.macosx-10.9-x86_64-3.7/fib.o -o /Users/user/pytorch/NLP学习/learning_2.0/fib.cpython-37m-darwin.so

    测试test.py:

    import fib
    fib.fib(100)

    返回:

    $ python test.py 
    1 1 2 3 5 8 13 21 34 55 89 

    如果输出两者的时间:

    (deeplearning) userdeMacBook-Pro:learning_2.0 user$ python fib.pyx 
    1 1 2 3 5 8 13 21 34 55 89 
    5.7220458984375e-05
    (deeplearning) userdeMacBook-Pro:learning_2.0 user$ python test.py 
    1 1 2 3 5 8 13 21 34 55 89 
    5.793571472167969e-05

    发现速度并没有很高的提升,很可能是操作本来就很简单,数值也很小,没什么优化的空间了。

    Primes项目

    给一个数值n,输出前n个质数(list)。

    写到primes.pyx中:

    def primes(int nb_primes):
        cdef int n, i, len_p
        cdef int p[1000]
        if nb_primes > 1000:
            nb_primes = 1000
    
        len_p = 0
        n = 2
        while len_p < nb_primes:
            for i in p[:len_p]:
                if n % i == 0:
                    break
            else:
                p[len_p] = n
                len_p += 1
            n += 1
        result_as_list = [prime for prime in p[:len_p]]
        return result_as_list

    setup.py:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules = cythonize("primes.pyx")
    )

    test.py:

    import primes
    import time
    
    time0 = time.time()
    primes.primes(10000)
    print(time.time() - time0)

    返回使用时间:

    0.0017080307006835938
    View Code

    prime.py原来:

    def primes(nb_primes):
        p = []
        if nb_primes > 1000:
            nb_primes = 1000
    
        n = 2
        while len(p) < nb_primes:
            for i in p:
                if n % i == 0:
                    break
            else:
                p.append(n)
            n += 1
        result_as_list = [prime for prime in p]
        return result_as_list
    
    if __name__ == '__main__':
        import time
        time0 = time.time()
        primes(10000)
        print(time.time() - time0)

    使用时间:

    0.030839204788208008

    可见的确快了不少!!!!!!

  • 相关阅读:
    solidworks中的一些标注尺寸的技巧
    SolidWorks 2-8草图绘制的一般过程
    SolidWorks 2-7 草图的约束【课程来自虎课网】
    SolidWorks 2-5 草图的编辑
    HTML 文本格式化实例--实体
    今天长进之redis的学习
    初步了解Quartz
    职场风云3
    内网穿透
    职场风云2
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/12971910.html
Copyright © 2011-2022 走看看