python中一些代码提速技巧

这篇具有很好参考价值的文章主要介绍了python中一些代码提速技巧。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

用set而非list进行查找

列表是一个有序的可重复元素的集合,它可以包含任意类型的对象。列表的实现通常使用动态数组,这意味着可以通过索引来快速访问元素。

集合是一个无序的不重复元素的集合,它只能包含可散列的对象(例如,数字、字符串等)。集合的实现通常使用哈希表或类似的数据结构,这使得它能够在O(1)的时间复杂度内查找元素。

由于集合使用哈希表实现,它可以在常数时间内(O(1))执行查找操作,而列表需要在最坏情况下遍历整个列表才能找到目标元素,其时间复杂度为O(n)。

集合是用来存储唯一元素的,所以在查找时,它不需要考虑是否有重复的元素,这也使得它在查找时更加高效。

list_d = [x**2 + 1 for x in range(1000000)]

set_d = (x**2 + 1 for x in range(1000000))

# 慢
1098987 in list_d

# 快
1098987 in set_d

用dict而非两个list进行匹配查找

看如下例子:

list_a = [2*i - 1 for i in range(1000000)]

list_b = [i**2 for i in list_a]

# 列表查找
print(list_b[list_a.index(876567)])

# 使用字典按照key查找
dict_ab = dict(zip(list_a, list_b))
print(dict_ab.get(876567, None))

与set同理,dict也是使用哈希表实现,也可以在常数时间内(O(1))执行查找操作。

优先使用for循环而不是while循环

示例:

import time


def time_cal(func):
    def wrapper():
        t1 = time.time()
        func()
        print(f"耗时:{time.time() - t1}")
    return wrapper


@time_cal
def func1():
    s = 0
    i = 0
    while s < 10000:
        s += 1
        i += 1


@time_cal
def func2():
    s = 0
    for i in range(10000):
        s += 1


if __name__ == "__main__":
    func1()
    func2()

结果如下:

耗时:0.0007779598236083984
耗时:0.00047516822814941406

循环代替递归

示例如下:

import time


def time_cal(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        func(*args, **kwargs)
        print(f"耗时:{time.time() - t1}")
    return wrapper


def func1(n):
    # 斐波那契函数
    return (1 if n in (1, 2) else (func1(n-1) + func1(n-2)))


@time_cal
def func2(n):
    if n in (1, 2):
        return 1
    a, b = 1, 1
    for i in range(2, n):
        a, b = b, a + b
    return b


if __name__ == "__main__":
    t1 = time.time()
    func1(30)
    print(f"耗时:{time.time() - t1}")

    func2(30)

结果如下:

耗时:0.1676180362701416
耗时:7.867813110351562e-06

递归虽然简单,但是可能存在以下问题:

  • 在递归中,每次函数调用都会涉及到压栈和弹栈的操作,这会导致额外的开销。每次函数调用都需要保存当前函数的状态(包括局部变量、返回地址等),而循环则避免了这种开销。
  • 另外有最大的函数调用栈深度限制。当递归的深度超过这个限制时,会引发栈溢出错误。
  • 一些编译器可以对尾递归做出优化,将其转换为类似循环的形式,从而避免了递归的开销。
  • 在一些问题中,递归可能会导致重复计算,因为递归往往会反复调用相同的子问题,而迭代可以使用循环变量来避免这种情况。

用缓存机制加速递归函数

上面说到,递归可能会导致重复计算,会反复调用相同的子问题。可以使用缓存减少重复计算。

代码如下:

import time
from functools import lru_cache

@lru_cache(100)
def func1(n):
    # 斐波那契函数
    return (1 if n in (1, 2) else (func1(n-1) + func1(n-2)))


if __name__ == "__main__":
    t1 = time.time()
    func1(30)
    print(f"耗时:{time.time() - t1}")

执行时间如下:

耗时:1.3828277587890625e-05

可以看到时间明显少了几个数量级。

用numba加速Python函数

未加速的代码:

import time


def time_cal(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        func(*args, **kwargs)
        print(f"耗时:{time.time() - t1}")
    return wrapper


def my_power(x):
    return x**2


@time_cal
def my_power_sum(n):
    s = 0
    for i in range(1, n+ 1):
        s += my_power(i)
    return s


if __name__ == "__main__":
    my_power_sum(1000000)

执行时间如下:

耗时:0.324674129486084

使用numba如下:

import time
from numba import jit


def time_cal(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        func(*args, **kwargs)
        print(f"耗时:{time.time() - t1}")
    return wrapper


@jit
def my_power(x):
    return x**2


@time_cal
@jit
def my_power_sum(n):
    s = 0
    for i in range(1, n+ 1):
        s += my_power(i)
    return s


if __name__ == "__main__":
    my_power_sum(1000000)

执行时间:

耗时:0.25246715545654297

使用collections.Counter加速计数

示例如下:

import time
from collections import Counter


def time_cal(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        func(*args, **kwargs)
        print(f"耗时:{time.time() - t1}")
    return wrapper


@time_cal
def func1(data):
    # 普通方法
    values_count = {}
    for i in data:
        i_count = values_count.get(i, 0)
        values_count[i] = i_count + 1
    print(values_count.get(4, 0))


@time_cal
def func2(data):
    # 加速方法
    values_count = Counter(data)
    print(values_count.get(4, 0))


if __name__ == "__main__":
    data = [x**2 % 1989 for x in range(2000000)]
    func1(data)
    func2(data)

运行结果如下:

8044
耗时:0.27747488021850586
8044
耗时:0.14070415496826172

使用collections.ChainMap加速字典合并

示例如下:

import time
from collections import ChainMap


def time_cal(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        func(*args, **kwargs)
        print(f"耗时:{time.time() - t1}")
    return wrapper


@time_cal
def func1(dic_a, dic_b, dic_c, dic_d):
    # 普通方法
    res = dic_a.copy()
    res.update(dic_b)
    res.update(dic_c)
    res.update(dic_d)
    print(res.get(9999, 0))


@time_cal
def func2(dic_a, dic_b, dic_c, dic_d):
    # 加速方法
    chain = ChainMap(dic_a, dic_b, dic_c, dic_d)
    print(chain.get(9999, 0))


if __name__ == "__main__":
    dic_a = {i: i + 1 for i in range(1, 1000000, 2)}
    dic_b = {i: 2*i + 1 for i in range(1, 1000000, 3)}
    dic_c = {i: 3*i + 1 for i in range(1, 1000000, 5)}
    dic_d = {i: 4*i + 1 for i in range(1, 1000000, 7)}

    func1(dic_a, dic_b, dic_c, dic_d)
    func2(dic_a, dic_b, dic_c, dic_d)

运行结果如下:

10000
耗时:0.05382490158081055
10000
耗时:4.57763671875e-05

使用map代替推导式进行加速

示例如下:

import time


def time_cal(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        func(*args, **kwargs)
        print(f"耗时:{time.time() - t1}")
    return wrapper


@time_cal
def func1():
    # 普通方法
    res = [x**2 for x in range(1, 1000000, 3)]


@time_cal
def func2():
    # 加速方法
    res = map(lambda x: x**2, range(1, 1000000, 3))


if __name__ == "__main__":
    func1()
    func2()

运行结果如下:

耗时:0.0947120189666748
耗时:1.0013580322265625e-05

使用filter代替推导式进行加速

示例如下:

import time


def time_cal(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        func(*args, **kwargs)
        print(f"耗时:{time.time() - t1}")
    return wrapper


@time_cal
def func1():
    # 普通方法
    res = [x**2 for x in range(1, 1000000, 3) if x % 7 == 0]


@time_cal
def func2():
    # 加速方法
    res = filter(lambda x: x%7 == 0, range(1, 1000000, 3))


if __name__ == "__main__":
    func1()
    func2()

运行如下:

耗时:0.03171205520629883
耗时:1.0013580322265625e-05

多线程加速IO密集型任务

低速方法
python中一些代码提速技巧,python进阶知识,python,后端高速方法
python中一些代码提速技巧,python进阶知识,python,后端

应用多进程加速CPU密集型任务

低速方法
python中一些代码提速技巧,python进阶知识,python,后端
高速方法
python中一些代码提速技巧,python进阶知识,python,后端

参考:
https://mp.weixin.qq.com/s/oF35_g4gdPeprHSvw4Mnyg文章来源地址https://www.toymoban.com/news/detail-727654.html

到了这里,关于python中一些代码提速技巧的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python 绘制箱型图一些技巧

    本篇是之前有一个需求,需要用python来画箱型图,但要求很多,所以我也不断再版,今天突然想起来这个东西可以总结一下,正好马上得思考下一步做啥了,有足够的空闲时间,所以准备把一些基础概念再好好复习一遍。 关于原理,这里推荐两篇本站写得比较好的: Matplot

    2024年02月03日
    浏览(39)
  • python的一些知识

            重新学习python 的开始从这个开始,         python 安装 Windows embeddable package (64-bit) Windows installer (64-bit) 有什么区别? Windows embeddable package (64-bit):这是一个嵌入式安装包,适用于需要将 Python 集成到其他应用程序或项目中的情况。它不包含图形界面的安装程序,只

    2024年04月16日
    浏览(32)
  • 【Python机器学习】深度学习——一些理论知识

            深度学习在很多机器学习应用中都有巨大的潜力,但深度学习算法往往经过精确调整,只适用于特定的使用场景。先学习一些简单的方法,比如用于分类和回归的多层感知机(MLP),它可以作为研究更复杂的深度学习方法的起点。MPL也被称为(普通)前馈神经网络,

    2024年01月16日
    浏览(48)
  • Python进阶知识(一)

    最简单的模块化方式,你可以把函数、类、常量拆分到不同的文件,把它们放在同一个文 件夹,然后使用 from your_file import function_name, class_name 的方式调 用。之后,这些函数和类就可以在文件内直接使用了。 看看上面的示例代码,get_sum() 函数定义在 utils.py,Encoder 和 Decoder

    2024年02月10日
    浏览(32)
  • Python进阶知识(三)

    在Python中,迭代器(Iterator)是一种用于遍历集合元素的对象。它是一个实现了迭代器协议(Iterator Protocol)的对象,该协议包含两个方法: __iter__ 和 __next__ 。 __iter__ 方法:返回迭代器对象自身。它在迭代开始之前被调用,用于初始化迭代器的状态。 __next__ 方法:返回迭代

    2024年02月10日
    浏览(38)
  • Python进阶知识(二)

    Python装饰器是一种用于修改函数或类的行为的特殊语法构造。装饰器允许在不修改原始代码的情况下,通过将函数或类包装在另一个函数中来添加额外的功能。 装饰器通常用于以下场景: 函数的日志记录:装饰器可以用来记录函数的调用信息,如函数名称、参数和返回值等

    2024年02月10日
    浏览(34)
  • Python进阶知识(四)

    在Python中, concurrent.futures 模块提供了一种简单而强大的并发编程方式,称为\\\"Futures\\\"。它基于线程池( ThreadPoolExecutor )和进程池( ProcessPoolExecutor )的概念,使并发任务的管理和执行更加方便。 使用 concurrent.futures 模块,你可以将任务提交给执行器(Executor),然后通过 Fu

    2024年02月11日
    浏览(34)
  • python一些小代码集

    (1)樱花树 (2)小猪佩奇 (3)皮卡丘 (4)烟花爆炸 (5)旗 (6)哆啦a梦 (7)多边形 (8)叮当猫2 (9)爱心 (10)基础画图 (11)圣诞树

    2024年02月03日
    浏览(25)
  • Python进阶知识:整理1 -> pySpark入门

    pySpark大数据分析过程分为3步: 数据输入、数据计算、数据输出 ,以下内容将重点介绍这三个过程   在数据输入完成后,都会得到一个 RDD类的对象 (RDD全称为弹性分布式数据集) map算子是将RDD的数据进行一条条处理(处理的逻辑基于map算子接收的处理函数),返回新的R

    2024年01月18日
    浏览(44)
  • Python基础知识进阶之数据爬虫

           爬虫是指利用网络抓取模块对某个网站或者某个应用中有价值的信息进行提取。还可以模拟用户在浏览器或者APP应用上的操作行为,实现程序自动化。简单来说就是我们把互联网有价值的信息都比喻成大的蜘蛛网,而各个节点就是存放的数据,而蜘蛛网的上蜘蛛比喻

    2024年02月09日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包