深度盘点:Python 7种提效增速的技巧

在工作中,我们常常面临着代码提速优化问题,本文就为大家介绍几种Python常用的提速技巧。

优化原则:
1.先保证代码可以正确运行,再进行性能优化
2.优化的选择通常是牺牲空间换取时间,所有我们需要权衡代价
3.着重优化代码耗时的部分,通篇优化通常会降低代码的可读性

0 定义耗时装饰器

# 可监控程序运行时间
import time
def clock(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print("共耗时: %s秒" % round(end_time - start_time, 2))
        return result
    return wrapper

1 避免使用全局变量

start_time = time.time()
size = 10000
for x in range(size):
    for y in range(size):
        z = x * y
end_time = time.time()
print('共耗时:%s秒' % round(end_time - start_time, 2))

# 共耗时:11.78秒,不推荐
# 使用局部变量
@clock
def multiplication():
    size = 10000
    for x in range(size):
        for y in range(size):
            z = x * y
multiplication()

# 共耗时: 5.5秒,提速50%

2 避免访问方法(函数)的属性,尽量使用from X import X

import math
@clock
def computeSqrt():
    result = []
    for i in range(10000000):
        # math方法访问sqrt属性
        result.append(math.sqrt(i))
computeSqrt()

# 不推荐,共耗时: 2.09秒
# 使用from X import X,直接访问sqrt
from math import sqrt
@clock
def computeSqrt():
    result = []
    for i in range(10000000):
        result.append(sqrt(i))
computeSqrt()

# 推荐,共耗时: 1.75秒

在【1】中我们讲到,局部变量的查找会比全局变量更快,因此对于频繁访问的变量append,通过将其改为局部变量可以加速运行。

from math import sqrt
@clock
def computeSqrt():
    result = []
    # 赋值给局部变量
    append = result.append
    for i in range(10000000):
        append(sqrt(i))
computeSqrt()

# 推荐,共耗时: 1.45秒

3 遍历优化

# 使用while进行遍历
@clock
def circulate():
    i = 0
    li = []
    append = li.append
    while i < 10000000:
        append(i*2)
        i += 1
    return li
circulate()

# 不推荐,共耗时:1.48秒
@clock
def circulate():
    li = []
    append = li.append
    # 使用for代替while
    for i in range(10000000):
        append(i*2)
    return li
circulate()

# for优于while,共耗时:1.09秒
@clock
def circulate():
    # 使用列表推导式
    return [i*2 for i in range(10000000)]
circulate()

# 推荐列表推导式,共耗时:0.88秒。但不适用于复杂计算。

4 减少内层for循环的计算

from math import sqrt
@clock
def inner():
    size = 10000
    for x in range(size):
        for y in range(size):
            # 相当于在重复计算sqrt(x)
            z = sqrt(x) + sqrt(y)
inner() 

# 不推荐,共耗时:19.00秒
from  math import sqrt
@clock
def inner():
    size = 10000
    for x in range(size):
        # 只计算一次sqrt(x),然后将它存了起来
        sqrt_x = sqrt(x)
        for y in range(size):
            z = sqrt_x + sqrt(y)
inner() 

# 推荐,共耗时:10.22秒

5 使用Numpy数据类型进行运算

因为Numpy底层是用C语言实现的,而Python这种脚本语言相比C/C++这种编译语言在效率和性能方面有天然劣势,所以我们可以引入Numpy包,对数据进行类型转换后再进行计算。

import numpy as np

li = [i for i in range(10000000)]

@clock
def npSpeed():
    # 使用Python方法
    sum(li)
npSpeed() 

# 共耗时0.79秒
import numpy as np

li = np.array([i for i in range(100000000)])
@clock
def npSpeed():
    # 使用Numpy方法
    np.sum(li)
npSpeed() 

# 共耗时0.11秒,速度约是Python的8倍

Numpy的优势在数据量越大时,体现的也会更加明显。所以在机器学习与深度学习项目任务中,Numpy的使用就非常频繁。

技术交流

欢迎转载、收藏、有所收获点赞支持一下!

深度盘点:Python 7种提效增速的技巧

目前开通了技术交流群,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友

  • 方式①、发送如下图片至微信,长按识别,后台回复:加群;
  • 方式②、添加微信号:dkl88191,备注:来自CSDN
  • 方式③、微信搜索公众号:Python学习与数据挖掘,后台回复:加群

深度盘点:Python 7种提效增速的技巧

上一篇:JESD204接口调试总结——Xilinx JESD204B IP testbench解析


下一篇:STM32L4系列芯片手册 - LTDC功能