V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
zerh925
V2EX  ›  Python

python 程序加速

  •  
  •   zerh925 · 2015-01-12 13:46:53 +08:00 · 4830 次点击
    这是一个创建于 3638 天前的主题,其中的信息可能已经有所发展或是发生改变。

    公司现在在用python做自动化开发,原型已开发完毕,现在就是提速,之前开发的时候完全不考虑时间成本,达到目的优先,现在就是要把2分钟的程序压缩到5秒以内。想请问下大家有哪些可行的手段?我能想到的multiprocess,Cython和SWIG用C来写模块。

    第 1 条附言  ·  2015-01-13 14:23:57 +08:00
    谢谢楼上各位的建议和意见。由于是自动化软件,经过profilling之后发现,memory不是问题,I/O是使用scipy.io读取的mat和读取pickle,mat有差不多5G,读取8秒左右,但是这个步骤只做一次,所以不是问题。现在主要是有一步需要使用levmar函数计算耗费大量的时间,这个函数现在使用的是第三方python库。
    目前总结:1.levmar使用原生的c开发的库,然后编译成python可调用的模块。
    2. 使用cuda加速图像处理。
    3. multiprocessing
    4. refactoring
    5. 优化业务逻辑
    35 条回复    2015-01-15 17:11:19 +08:00
    loading
        1
    loading  
       2015-01-12 14:01:02 +08:00 via Android
    用go重构。
    geeklian
        2
    geeklian  
       2015-01-12 14:13:03 +08:00 via iPhone
    2分钟压缩到5秒...
    虽然大家都知道python比C慢,但还没到这地步吧。
    cevincheung
        3
    cevincheung  
       2015-01-12 14:15:00 +08:00
    为什么我想说“多机并行计算”呢……
    min
        4
    min  
       2015-01-12 14:16:42 +08:00
    优化的第一步永远是先profiling
    yakczh
        5
    yakczh  
       2015-01-12 14:16:46 +08:00
    pypy

    Python 2.7.3 (f66246c46ca30b26a5c73e4cc95dd6235c966b8f, Jul 30 2013, 09:27:06)
    [PyPy 2.0.2 with GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
    zerh925
        6
    zerh925  
    OP
       2015-01-12 14:17:10 +08:00
    @geeklian 因为程序中间最耗时间的部分可以并行的
    zerh925
        7
    zerh925  
    OP
       2015-01-12 14:17:35 +08:00
    @yakczh 谢谢 我去google一下
    zerh925
        8
    zerh925  
    OP
       2015-01-12 14:18:53 +08:00
    thx. will do.
    zerh925
        9
    zerh925  
    OP
       2015-01-12 14:19:15 +08:00
    @loading 不是很明白 改用go语言吗?为什么
    shiny
        10
    shiny  
       2015-01-12 14:22:16 +08:00
    先分析瓶颈
    messense
        11
    messense  
       2015-01-12 14:34:48 +08:00
    性能瓶颈如果是 CPU 计算密集型的试试 multiprocessing,network IO 密集型的多线程也能有一定程度的提升。
    zerh925
        12
    zerh925  
    OP
       2015-01-12 14:37:57 +08:00
    @messense 非常感谢。正是计算密集型的。
    tabris17
        13
    tabris17  
       2015-01-12 14:39:45 +08:00
    想要速度当初就不要选python吗,试试pypy,不行就拉倒吧
    zerh925
        14
    zerh925  
    OP
       2015-01-12 14:41:10 +08:00
    @tabris17 老板是偏执狂。
    skybr
        15
    skybr  
       2015-01-12 14:47:07 +08:00   ❤️ 1
    Cython就可以了。

    把几个数值类型的PyObject声明成C类型的, 套在with nogil里。

    外面用线程池就好了。
    skybr
        16
    skybr  
       2015-01-12 14:48:52 +08:00   ❤️ 1
    涉及到动态链接库, 比如标准库的IO和一些C扩展, PyPy可能反而比CPython慢。
    dreampuf
        17
    dreampuf  
       2015-01-12 14:50:02 +08:00   ❤️ 1
    两个思路都是对的,并行利用多核以及用更快的底层。

    并行方面看看是IO还是CPU,IO的话用gevent试试,耗时不大,CPU的话有一些计算框架,但都需要时间去采坑,而且不一定都合适。用原始的multiprocess的话,主要问题是数据交互方面非常原始,得
    踩很多坑。
    更换底层可以试试Cython,在不调用其他类库的纯计算可以做到两个量级的优化。或者用PyPy,Pyston。

    Python平台资源丰富,没有什么过不去的坎,动不动嚷嚷换一门语言,似乎是那门语言小白特有的情怀。
    clino
        18
    clino  
       2015-01-12 14:50:58 +08:00   ❤️ 1
    建议用 cython 试试
    zerh925
        19
    zerh925  
    OP
       2015-01-12 15:00:17 +08:00
    @dreampuf 感谢
    zerh925
        20
    zerh925  
    OP
       2015-01-12 15:00:45 +08:00
    @skybr 谢谢建议
    zhicheng
        21
    zhicheng  
       2015-01-12 15:03:09 +08:00
    打算靠换个语言或者改几个变量类型就把性能提升 20 多倍不太现实。楼主还是在工程上找解决办法,比如是不是有些流程是不必要的。
    sunus
        22
    sunus  
       2015-01-12 15:10:24 +08:00   ❤️ 1
    做调优的第一步是找到时间花在哪里了?
    lupino
        23
    lupino  
       2015-01-12 15:27:06 +08:00
    异步,并发
    henices
        24
    henices  
       2015-01-12 15:43:15 +08:00
    @sunus 说的完全正确。

    看看瓶颈在哪里, CPU ? IO ? Memory ?
    找到问题之后就可以作出相应的代码调整了。
    20015jjw
        25
    20015jjw  
       2015-01-12 16:31:34 +08:00
    Spark?
    ihciah
        26
    ihciah  
       2015-01-12 16:38:45 +08:00
    上GPU?
    thankyourtender
        27
    thankyourtender  
       2015-01-12 17:26:04 +08:00
    加机器
    wdlth
        28
    wdlth  
       2015-01-12 18:41:00 +08:00
    如果是密集计算,再怎么优化还是看你的电脑的运算速度,像破解密码一样,可以试试通过GPU进行加速,将算法改写支持多线程、并行计算等。
    typcn
        29
    typcn  
       2015-01-12 18:51:00 +08:00
    改用C语言
    alsotang
        30
    alsotang  
       2015-01-12 20:30:38 +08:00
    说了半天也不详细描述一下场景
    GeekGao
        31
    GeekGao  
       2015-01-13 06:28:42 +08:00
    @alsotang 顶。lz不表述清楚具体场景就求建议,这帮人,不知道具体场景就开始指挥,哎。

    我怀疑lz代码有问题。
    alsotang
        32
    alsotang  
       2015-01-13 11:52:34 +08:00
    @GeekGao 我判断楼主应该是遇到了 cpu 方面的瓶颈而不是 io 的,但他还是需要详细描述下
    zerh925
        33
    zerh925  
    OP
       2015-01-13 14:22:55 +08:00
    谢谢楼上各位的建议和意见。由于是自动化软件,经过profilling之后发现,memory不是问题,I/O是使用scipy.io读取的mat和读取pickle,mat有差不多5G,读取8秒左右,但是这个步骤只做一次,所以不是问题。现在主要是有一步需要使用levmar函数计算耗费大量的时间,这个函数现在使用的是第三方python库。
    目前总结:1.levmar使用原生的c开发的库,然后编译成python可调用的模块。
    2. 使用cuda加速图像处理。
    3. multiprocessing
    4. refactoring
    5. 优化业务逻辑
    ruoyu0088
        34
    ruoyu0088  
       2015-01-15 16:13:14 +08:00   ❤️ 1
    我相信你使用的levmar一定不是纯Python的,它一定是使用的某个C/C++/Fortran语言编写的库。你能说说你使用的是哪个库吗?

    levmar算法需要回调函数,这个回调函数你用Python编写,所以唯一能提高速度的就是用编译语言编写这个回调函数。

    首先你需要测试瓶颈是否是这个回调函数。如果是的话,你可以用Cython包装C语言的levmar库,然后接收一个编译之后的回调函数。下面是一个例子:

    http://nbviewer.ipython.org/github/ruoyu0088/openbooks/blob/master/cython_ctypes_cffi_numba_calls.ipynb

    下面是用cython编写的levmar,你可以仿照上面的例子修改这个库,让它能接受编译之后的回调函数。

    https://github.com/tkanmae/levmar
    zerh925
        35
    zerh925  
    OP
       2015-01-15 17:11:19 +08:00
    @ruoyu0088 万分感谢!非常有用。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   947 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:58 · PVG 04:58 · LAX 12:58 · JFK 15:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.