python代码性能优化技巧_Python 代码优化技巧(一)

Python相比于C++来说有着十分用户友好的编程方式与众多的机器学习和深度学习库,入门快、学习轻松,但其性能劣势一直为人诟病。因此,很多工程师致力于提高python代码性能。本文记录下目前我所知道的Python代码加速方法!

Numba

Numba 是一个开源的 JIT 编译器可以纯Python和Numpy代码转为快速地机器码执行,但其不能加速Pandas代码而且在多线程的任务出容易出错!

numba可以将python变为C的性能,并且所有代码的改动点只需要加一行代码!

下面以官方计算$\pi$的例子来测试性能提升幅度:from numba import jit

import random

import time

def monte_carlo_pi(nsamples):

acc = 0

for i in range(nsamples):

x = random.random()

y = random.random()

if (x ** 2 + y ** 2) < 1.0:

acc += 1

return 4.0 * acc / nsamples

@jit(nopython=True)

def monte_carlo_pi_numba(nsamples):

acc = 0

for i in range(nsamples):

x = random.random()

y = random.random()

if (x ** 2 + y ** 2) < 1.0:

acc += 1

return 4.0 * acc / nsamples

def test_time(func, *args, **kwargs):

start = time.time()

res = func(*args)

end = time.time()

return end-start

magnitude1 = 10000

print(f"Magnitude {magnitude1} : non-accelerated costed time:{test_time(monte_carlo_pi, magnitude1)}")

print(f"Magnitude {magnitude1} : accelerated costed time:{test_time(monte_carlo_pi_numba, magnitude1)}")

magnitude2 = 100000

print(f"Magnitude {magnitude2} : non-accelerated costed time:{test_time(monte_carlo_pi, magnitude2)}")

print(f"Magnitude {magnitude2} : accelerated costed time:{test_time(monte_carlo_pi_numba, magnitude2)}")Magnitude 10000 : non-accelerated costed time:0.004992485046386719

Magnitude 10000 : accelerated costed time:0.2682771682739258

Magnitude 100000 : non-accelerated costed time:0.053856611251831055

Magnitude 100000 : accelerated costed time:0.0010225772857666016

从上述时间测试中可以看出,对于量级小于100000的计算量来使用Numba加速发现加速效果并不佳,而且还可能减慢运行时间!因此需要根据自己的数据量来选择是否使用Numba!

上面谈到Numba仅能加速纯python操作和numpy操作,那么对于数据分析中另一常用库 pandas 如何加速呢?写下自己了解的两种方法。

Python 多线程

python多线程可以加速任意的操作,加速的上限取决于电脑的性能,可以使用python多线程并行处理来加速pandas操作。操作代码如下:import numpy as np

import pandas as pd

from multiprocessing import cpu_count, Pool

def parallelize(func, df):

""" Split data into max core partitions and execute func in parallel.

https://www.machinelearningplus.com/python/parallel-processing-python/

Parameters

----------

df : pandas Dataframe

func : any functions

Returns

-------

data : pandas Dataframe

Returned dataframe of func.

"""

cores = cpu_count()

data_split = np.array_split(df, cores)

pool = Pool(cores)

data = pd.concat(pool.map(func, data_split), ignore_index=1)

pool.close()

pool.join()

return data

测试多线程处理的性能:nsamples = 100

data = pd.DataFrame({"a": np.random.rand(nsamples), "b": np.random.rand(nsamples)})

def func(data):

"""test func."""

return data["a"].apply(lambda x: np.sqrt(x)) - data["b"] ** 2

if __name__ == '__main__':

print(f"non-accelerated costed time:{test_time(func, data)}")

print(f"accelerated costed time:{test_time(parallelize, func, data)}")

注意:在Windows上要想使用multipropressing模块,必须把有关进程的代码写 if __name__ == ‘__main__’ 语句中,才能正常使用Windows下的进程模块,否则进程将不会停止。Unix/Linux下则不需要。 这个Bug真是让我头疼半天!

Modin 库

Modin 库是pandas库的升级版,同样是使用多核调度的方法来加速pandas中的操作,和numba一样操作简单,它只需增加一行代码来优化而不需要自己控制调度过程!

一行代码加速确实非常香,但缺点是需要安装底层依赖$ray$ 或者 $dask$,此外也不是完全支持pandas操作,待进一步完善。可以满足日常需求!参考: modin-project/modin

给出官方的测试效果,其它细节可以参考官方文档:文档说明

目前暂时用不到这库,因此以后有需求的时候再补充使用说明吧!

联系作者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值