美文网首页IT狗工作室
第5篇:Cython中的循环结构优化

第5篇:Cython中的循环结构优化

作者: 铁甲万能狗 | 来源:发表于2020-04-18 18:35 被阅读0次

    Python的for和while循环是灵活和高级的;它们的语法是自然的,读起来像伪代码。Cython支持for和while循环,无需修改。由于循环在本质上通常占据程序运行时的大部分时间,因此需要记住一些指针,以确保Cython可以将Python循环结构转换为高效的C类似结构。

    Cython也会自动将循环索引变量i键入为int, 前提是我们不在循环体中的表达式中使用索引。如果我们确实在表达式中使用i,则Cython无法自动推断该操作是否会溢出,并且保守地拒绝推断C整数类型

    下面的示例其实和一个原生Python版本的for循环等效的,传入的变量N和索引i都是动态类型

    %%cython
    
    cpdef long long calc():
        N=10000000
        cdef long long res=0
        for i in range(N):res+=i
        return res
    

    运行的时间消耗

    我们从Cython编译的代码可以知道,原生版本的Python版本的for循环,在Cython编译后的C级别代码,如下图。
    也就是在每经历一个循环内部都经历了如下Python内部C级别下的函数检查 PyList_CheckExactPyList-GET_ITEM (或 PySequence_ITEM)并获取range(N)中当前的索引i,遍历的规模达到一个较大的数量级,效率自然慢

    高效的做法是

    • 将传入range函数的参数静态指定为C类型的整数
    • 为索引变量i静态指定C整数类型
    %%cython -a
    
    cpdef long long calc2():
        
        cdef long N=10000000
        cdef long i
        
        cdef long long res
        for i in range(N):res+=i
    
        return res
    

    运行的时间消耗


    由于在执行循环前,对相关的循环变量做静态类型绑定运行的速度提升到原来的13倍,相应地Cython编译器生成的C代码也非常简洁

    但如果上面的示例的for in 循环内部涉及到容器(列表,元组,字典等)的循环时,根据情况,类型静态化循环索引变量可能会导致更多开销。若要高效地循环容器,可以考虑使用如下建议

    • 将容器转换为等效的C ++容器
    • 使用类型化的内存视图

    这些方案可能会减少循环开销。我们将在后续了解到更多关于优化循环体的知识

    相关文章

      网友评论

        本文标题:第5篇:Cython中的循环结构优化

        本文链接:https://www.haomeiwen.com/subject/xrabvhtx.html