Pythran简单使用

Pythran简介:

Pythran通过预先编译,将python代码转为C++代码的 后缀为 .so 的文件,从而 在运行时获得更快的运行速度;

 

安装步骤:

Mac OS系统安装方式:

$> pip install pythran
$> brew install openblas
$> printf '[compiler]\nblas=openblas\ninclude_dirs=/usr/local/opt/openblas/include\nlibrary_dirs=/usr/local/opt/openblas/lib' > ~/.pythranrc

其他系统请点击链接

 

使用示例:

先编写如下代码

# -*- coding: utf-8 -*-
"""
(C) rgc
All rights reserved
create time '2021/1/26 10:50'

Usage:

"""


def a(b):
    """
    主要用来测试 被编译函数可以调用未被编译的函数
    注意 此函数入参 不能是 *args 等可变类型,否则编译失败(Varargs not supported)
    :param b:
    :return:
    """
    print('df', b)


# 注意:如下行注释必须存在,声明入参类型,Pythran通过此 进行编译; 注意 函数名不能错误;
# 如下 声明入参  int list 表示 入参类型时list,元素是int类型
# pythran export dprod(int list, int list)
def dprod(l0, l1):
    """

    :param l0: 入参类型时list,元素是int类型
    :param l1: 入参类型时list,元素是int类型
    :return:
    """
    a(2)
    return sum(x * y for x, y in zip(l0, l1))


# pythran export drop1(int[], int list,str:float dict)
def drop1(l0, l1, _dict):
    """

    :param l0: 入参类型为 numpy.array 元素时 int类型
    :param l1: 入参类型时list,元素是int类型
    :param _dict: 入参类型时 dict, key是str类型,value是 float类型
    :return:
    """
    a(2)
    l1.append(l0[-1])
    print(type(l0))
    for k, v in _dict.items():
        print(k, v)
    return l1

命令行中运行如下命令 如果编译通过 会生成 一个 pythran_use.cpython-36m-darwin.so 文件

pythran pythran_use.py

在另一个py文件中 代码如下,运行即可:

# -*- coding: utf-8 -*-
"""
(C) rgc
All rights reserved
create time '2021/1/26 11:04'

Usage:

"""

import numpy as np
# 像正常模块一样导入即可
from pythran_use import drop1

if __name__ == '__main__':
    l0 = np.array([1, 2, 3])
    print(type(l0))
    print(drop1(l0, [4, 5, 6], {'a': float(1), 'b': float(2)}))

 

 

函数入参设置:

argument_type = basic_type
              | (argument_type+)    # this is a tuple 元祖
              | argument_type list    # this is a list 列表
              | argument_type set    # this is a set 集合
              | argument_type []+    # this is a ndarray, C-style 是个ndarray
              | argument_type [::]+    # this is a strided ndarray
              | argument_type [:,...,:]+ # this is a ndarray, Cython style
              | argument_type [:,...,3]+ # this is a ndarray, some dimension fixed
              | argument_type:argument_type dict    # this is a dictionary 是个字典

basic_type = bool | byte | int | float | str | None | slice
           | uint8 | uint16 | uint32 | uint64 | uintp
           | int8 | int16 | int32 | int64 | intp
           | float32 | float64 | float128
           | complex64 | complex128 | complex256

具体用法(如上示例代码):

  • 如一个 函数 入参 为  numpy.ndarray 每个元素类型为 float;   如果数据结构是 矩阵(或二维数组) 用 float[:, :]    如果数据结果是 列表(或一维数组)用 float[:] 或 float[] 
  • 如一个 函数 入参 为  int 类型,则 入参 声明为: int
  • 如一个函数 入参 为   list 类型,每个元素为 int类型 则入参 声明为: int  list
  • 如一个函数 入参 为   dict 类型,key为str类型,value为 int类型 则入参 声明为:  str:int dict

 

使用限制:

  • 对 dict的 values()方法 调用失败; 但是 可以使用 items()方法;
  • 对 numpy和scipy的部分方法 无法预编译,会报错; 如 numpy.reshape, numpy.ndarray的 操作如 "array[b <= a, :]"  和 scipy的fmin_slsqp
  • 被编译py文件内 如果有函数 如 func_a 未 添加注释 编译声明( # pythran export func_a()), 则 其他模块文件中无法导入此函数,因为此函数未在 被编译后的 .so文件中;
  • 注意 对 numpy,scipy 及python内置的 各种可以预编译的方法 都在  pythran/tables.py文件的  MODULES 属性中,请自行查看; 如果 MODULES中存在对应方法,但是编译 报 没有对应属性 的错误,说明是自己的问题,可以进行修复,否则 就放弃用此包吧; 如下图

 

总结:

  • 每次代码改变时 需要从新编译一次
  • Pythran的预编译 和 Numba的运行时编译正好相反; Numba第一次运行时进行编译,所以会较慢; 而Pythran将编译放在了 代码运行前;
  • Numba 在numpy的大数据量的for循环时 比较特长;
  • NumExpr 在涉及到 一堆的数学计算时比较特长,但是支持的numpy函数较少; 
  • Pythran 则适用于 大众情况,且对numpy的函数支持比NumExpr多一些,更适用于 list,dict 等的数据处理 及 numpy操作;
  • 具体 使用 Pythran预编译后的性能 如何,需要结合实际代码及数据量使用 timeit等工具进行测评;
  • 此包使用时的 坑点很多,使用时需要耐心试错,且 国内 相关参考资料较少;

 

相关链接:

https://pythran.readthedocs.io/en/latest/MANUAL.html#advanced-usage

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值