五个提升 Python 速度的优化技巧

Python   2024-11-01 10:20   775   2  

在这篇文章中,我将分解一些我见过的(甚至自己也犯过)最常见的影响性能的错误。最重要的是,我们不仅仅讨论不该做什么——我会给你提供可行的修复方法和代码示例,让你的脚本变成精简、高效的Python机器。

错误 #1:像1999那样循环

我和其他开发者一样,对精心制作的for循环有着强烈的喜爱。它们构成了我们工作的很大一部分基础。然而,当讨论纯粹的速度时,特别是处理大型数据集时,那些可靠的循环开始显得更像是负担而不是助力。

示例:让我们加一些数字

想象你需要计算一个巨大数字列表的平方和。以下是循环的方式:

复制

numbers = [1, 2, 3, 4, 5, ... , 10000]  # A big list
total = 0for number in numbers:
    squared = number * number
    total += squared1.2.3.4.5.

看起来无害,对吧?但在幕后,Python为每个元素进行了大量的单独计算。

修复方法:NumPy来拯救!

这就是NumPy像超级英雄一样出现的地方。它全是关于矢量化——一次性对整个数组执行操作。让我们重写那个示例:

复制

import numpy as np

numbers = np.array([1, 2, 3, 4, 5, ... , 10000])  squared = numbers * numbers  # Vectorized squaring!total = squared.sum()1.2.3.4.5.

NumPy不是逐个处理元素,而是一次性处理整个计算。

额外提示:易于理解的折中方案

列表推导式:

复制

total = sum(number * number for number in numbers)1.

它们通常比传统循环更快,但在激烈的数值计算中可能无法与NumPy的强大力量相媲美。

错误 #2:使用错误的工具

想象一下,只用锤子建造房子。当然,你可以完成它,但会是混乱的。同样,对于Python——完全依赖列表来完成所有任务,就像被绑着一只手编程一样。

示例:我的电话号码在哪里?

假设你有这样一个联系人列表:

复制

contacts = [
    {"name": "Alice", "phone": "123-4567"},
    {"name": "Bob", "phone": "789-0123"},
    # ... more contacts]1.2.3.4.5.

找到Bob的号码意味着扫描整个列表,可能需要检查每个联系人。

修复方法:拥有超能力的数据处理结构

字典:你的快速查找伙伴如果你按键(比如“名字”)搜索,字典是你的救星。

复制

contacts_dict = {
    "Alice": "123-4567",
    "Bob": "789-0123",
    # ... more contacts}bobs_number = contacts_dict["Bob"]  # Instant access!1.2.3.4.5.6.

集合:强制唯一性需要跟踪唯一的网站访问者吗?集合会自动丢弃重复项。

复制

unique_visitors = set()unique_visitors.add("192.168.1.100")unique_visitors.add("124.58.23.5")unique_visitors.add("192.168.1.100")  # No duplicate added1.2.3.4.

了解你的工具箱Python给你提供了更多:有序字典、双端队列等。知道何时使用它们是好脚本和优秀脚本的区别。

错误 #3:在黑暗中优化

你熟悉那种感觉,当你确信你的代码很慢,但对原因一无所知。这就像试图在没有手电筒的情况下修补滴水的天花板。令人沮丧!这就是分析器的用武之地。

示例:意外的罪魁祸首

假设你有一个复杂的函数来计算斐波那契数。你投入了灵魂来完善数学,但它仍然很慢。结果,瓶颈可能是一些狡猾的东西,比如你如何将结果记录到文件中。

修复方法:cProfile来拯救!

Python内置的cProfile模块是你的性能侦探。以下是如何使用它:

复制

import cProfile

def my_function():
    # Your code to be profiled

cProfile.run('my_function()')1.2.3.4.5.6.

这会产生大量统计数据。需要关注的关键事项:

  • ncalls:函数被调用了多少次。

  • tottime:在函数中花费的总时间。

  • cumtime:像tottime一样,但包括在其中调用的所有函数所花费的时间。

筛选线索这些数字将指出你真正的瓶颈,帮助你将优化工作集中在它们将产生最大影响的地方。

错误 #4:DIY陷阱

从头开始构建一切的冲动很强。我懂!但有时,重新发明轮子就像决定步行穿越国家而不是乘坐飞机。Python有你的背,有非常优化的内置函数。

示例:让我们排序

需要对数字列表进行排序吗?你可以编写你的冒泡排序实现……或者你可以使用Python的sorted():

复制

my_list = [5, 3, 1, 4, 2]# The long way (probably pretty slow)def my_bubble_sort(list): 
   # ... your sorting code here

# The Pythonic way
sorted_list = sorted(my_list)1.2.3.4.5.6.7.8.

很有可能,你自己的排序算法甚至无法接近内置的效率。

修复方法:探索宝库

Python标准库是开发者的最好朋友。了解这些强大的工具:

  • itertools:通过迭代器(想想高级循环以提高效率)增强你的工作

  • heapq:用于管理堆(优先队列有人吗?)

  • bisect:保持排序列表的顺序,速度极快。

记住:花时间学习内置函数是后来优化节省的时间。

错误 #5:与硬盘聊天太多

将你的计算机内存(RAM)视为你的超快速工作区,将你的硬盘视为城市的存储仓库。每次你访问或修改文件,就像派遣信使来回奔波。太多的行程,你的代码开始感受到等待。

示例:逐行减速

假设你正在处理一个庞大的日志文件:

复制

with open("huge_log.txt", "r") as file:
    for line in file:
        # Process each line slowly1.2.3.

每读取一行意味着从你的硬盘单独获取。

修复方法:更聪明地工作,而不是更努力

一次读取全部(如果合适):对于较小的文件,有时将整个内容吸入内存是最快的:

复制

with open("huge_log.txt", "r") as file:
    contents = file.read() 
    # Process contents in memory1.2.3.

缓冲来拯救:当你需要细粒度控制时,缓冲可以拯救:

复制

with open("huge_log.txt", "r") as file:
    while True:
        chunk = file.read(4096)  # Read in chunks        if not chunk:
            break
        # Process the chunk1.2.3.4.5.6.

以块而不是字节思考最小化那些去“仓库”的行程会产生巨大的差异。

博客评论
magicboxpro.flowcartz.com
说:

https://magicboxpro.flowcartz.com/

 

I am now not sure the place you're getting your info, however great topic.

I must spend some time learning more or figuring out more. Thank you for great info I used to be searching for this information for my

mission.

https://watchnow.gomuviz.com
说:

https://watchnow.gomuviz.com/

 

I enjoy what you guys are usually up too.

Such clever work and exposure! Keep up the amazing works guys I've you guys to our blogroll.

1
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。
闲言碎语
现在男女之间的恋爱,总是答应太快,结果分手也快。人性的规律是容易得到的就容易放弃。凡是通过努力得到的,不管是感情还是物品,都会使人顿生珍惜之感。所以在感情上,当有人追求时,内心的一份矜持是必要的,即使心里很爱,也需要给追求者时间和难度,这样两人走到一起才会珍惜感情、地久天长。
赞赏支持

如果觉得博客文章对您有帮助,异或土豪有钱任性,可以通过以下扫码向我捐助。也可以动动手指,帮我分享和传播。您的肯定,是我不懈努力的动力!感谢各位亲~