社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

求你不要再用这几个 Python 编码了,太慢了...

数据STUDIO • 1 年前 • 246 次点击  


Python 脚本的运行速度一直都是开发者诟病的地方,无论是网站运行迟缓,还是数据分析工作长达数小时,代码运行缓慢将影响所有相关人员,使其效率大打折扣,甚至可能危及项目的成功。

在本文中,我将介绍一些的最常见的拖垮性能的一些编程代码,并推荐相应的解决方法,为你的 Python 涡轮增压!当然,如果你不限于此,推荐你看下前面推荐 mojo 语言 比 Python 快几万倍:比Python快9万倍!AI编程语言Mojo正式开源

01 循环

我们通常对for循环情有独钟,在需要进行大量作业时,首先想到的就是使用 for 循环。而在优化速度时,尤其是在讨论大型数据集时,这些循环简直就是噩梦般存在。

数字加法:将一大串数字的平方相加,首先使用一个循环方法:

numbers = [12345, ... , 10000]  # A big list
total = 0
for number in numbers:
    squared = number * number
    total += squared

在引擎下,Python 会对每个元素进行大量的单独计算。

解决方法:NumPy

这时,NumPy 就像超级英雄一样,它的矢量化简直无敌!一次性对整个数组执行操作。

import numpy as np

numbers = np.array([12345, ... , 10000])  
squared = numbers * numbers  # Vectorized squaring!
total = squared.sum()

NumPy 不需要逐个元素计算,而是一气呵成地处理整个计算过程。

折中方案

列表推导式:

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

它们通常比传统循环更快,但在进行高强度数值计算时,可能无法与 NumPy 匹敌。

02 错用工具

对于 Python 来说,仅仅依靠列表来完成所有任务无异于只用一只手编程。

查询电话号码:假设有一个这样的联系人列表:

contacts = [
    {"name""Alice""phone""123-4567"},
    {"name""云朵君""phone""789-0123"},
    # ... more contacts
]

查找云朵君的号码意味着要扫描列表,可能要检查每一个联系人。

解决方法:具有超能力的数据结构

  • 字典:快速查找的好帮手

如果要通过关键字(如 "姓名")进行搜索,字典就是你的救星。

contacts_dict = {
    "Alice""123-4567",
    "云朵君" "789-0123",
    # ... more contacts
}
bobs_number = contacts_dict["云朵君"]  # Instant access!
  • 集合: 强制执行唯一性

需要跟踪唯一的网站访问者吗?集合会自动删除重复项。

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 added

Python 还提供了更多超级有用的工具:有序字典、特殊队列 deques 等。了解何时使用这些工具标志着优秀与卓越脚本之间的区别。

03 在黑盒中优化

你一定对这种感觉很熟悉,虽然发现了代码运行缓慢,但却对原因一无所知时。这就好比在没有灯光的情况下修灯泡。

假设你有一个计算斐波那契数字的函数。你费尽心力来完善数学推理,但速度仍然很慢。结果发现,瓶颈可能是某些看不见的东西,比如在边运行代码边将结果记录到磁盘文件中。

解决方法:cProfile 来救场!

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

import cProfile

def my_function():
    # Your code to be profiled

cProfile.run('my_function()')

这将生成大量统计数据。主要内容如下

  • ncalls: 函数被调用的次数。
  • tottime: 在函数中花费的总时间。
  • cumtime: 与 tottime 类似,但包括调用其中所有函数所花费的时间。

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

04:重复造轮子

重新造轮子就像决定徒步穿越整个国家,而不是乘坐飞机前往目的地。就像上一步介绍的python工具一样,其实Python 真的有很多神奇的内置函数来帮助你完成你的工作。要不然python怎么会被戏称胶水语言呢。

排序:可以编写自己的冒泡排序实现......或者使用 Python 的sorted():

my_list = [53142]

# The long way (probably pretty slow)
def my_bubble_sort(list): 
   # ... your sorting code here

# The Pythonic way
sorted_list = sorted(my_list)

很有可能,你的自定义排序算法甚至无法达到内置算法的效率。当然,如果你是编程超级高手,不用在意这些🤓

解决方法:借助标准库

Python 标准库简直就你最好最强大的朋友。比如用来解决本次问题的强大的工具有:

  • itertools: 使用迭代器为你的工作增效(想想高级循环的效率)
  • heapq:用于管理堆(优先队列)
  • bisect:以迅雷不及掩耳之势让排序列表保持有序。

学习内置标准库的时间就是节省下来的优化时间。

05:与硬盘交互太多

将电脑内存(RAM)视为超快速工作区,将硬盘视为另一端的存储仓库。每次访问或修改文件,就相当于派遣一名信使来回奔波。往返次数过多,你的代码就会开始感觉到等待时长。就像第三节提到的,边运行代码,边存储文件到磁盘,还有往复读取、写入的更糟糕的过程。

逐行缓慢:假设正在处理一个庞大的日志文件:

with open("huge_log.txt""r"as file:
    for line in file:
        # Process each line slowly
  • 每读取line,就意味着要从硬盘上单独取一次数据。

解决方法:更聪明地工作,而不是更努力地工作

  • 一次读完(如果合适): 对于较小的文件,有时最快的方法是将其全部读入内存:
with open("huge_log.txt""r"as file:
    contents = file.read() 
    # Process contents in memory
  • 缓冲拯救: 当你需要细粒度的控制时,缓冲功能就能拯救你:
with open("huge_log.txt""r"as file:
    while True:
        chunk = file.read(4096)  # Read in chunks
        if not chunk:
            break
        # Process the chunk

以块为单位,而不是以字节为单位思考尽量减少前往 "仓库" 的次数,这将带来巨大的不同。


🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析数据可视化机器学习与数据挖掘爬虫  等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/168835
 
246 次点击