当前位置: 首页 > news >正文

提升Python代码性能的六个技巧

文章目录

  • 前言
  • 为什么要写本文?
  • 1、代码性能检测
    • 1.1、使用 timeit 库
    • 1.2、使用 memory_profiler 库
    • 1.3、使用 line_profiler 库
  • 2、使用内置函数和库
  • 3、使用内插字符串 f-string
  • 4、使用列表推导式
  • 5、使用 lru_cache 装饰器缓存数据
  • 6、针对循环结构的优化
  • 7、选择合适算法和数据结构
  • 8、推荐书籍
  • 结语

前言

🗿 hello大家好啊,我是作家桑。本文为大家介绍提升 Python 代码性能的六个技巧,希望大家看完有所收获。


为什么要写本文?

首先讨厌 Python 的人呢,总是会吐槽 Python 的性能速度慢。但是事实上程序运行速度的快慢都在很大程度上取决于编写程序的开发人员,以及开发人员的算法能力和对代码的优化能力。Python 虽然在运行效率上有所欠缺,但是值得一提的是在开发效率方面 Python 却比其它编程语言高很多。为了弥补 Python 在运行效率上的不足,所以笔者开始创作本文为大家介绍提升 Python 代码性能的技巧。

某乎上的一位网友对 Python 的吐槽:
在这里插入图片描述

1、代码性能检测

在对代码进行优化之前,通常需要检测是哪些代码片段拖慢了整个程序的运行速度。在这里笔者推荐三个方法帮助开发者们找出程序的瓶颈,这样就知道应该把注意力放在哪里。

以一个 Python 实现斐波那契数列的程序为示例:

# 斐波那契数列
def Fibonacci():a, b = 0, 1i = 0while i < 100:print(b)a, b = b, a+bi += 1Fibonacci()

1.1、使用 timeit 库

timeit 模块是 Python 的内置模块。timeit 模块致力于衡量代码的性能,模块内提供了许多个函数和类,以便开发者能够精确地测量代码的执行时间。timeit 模块用法较为简单,适合用来计算一小段代码的运行时间。

代码示例:

import timeit def Fibonacci():a, b = 0, 1i = 0while i < 100:print(b)a, b = b, a+bi += 1result = timeit.timeit(Fibonacci, number=5)print(f"Fibonacci函数的运行时间为: {result}")

运行结果:
在这里插入图片描述

1.2、使用 memory_profiler 库

memory_profiler 是 Python 的第三方库(需要使用 pip 命令进行安装),是一个可根据每行代码查看内存占用的工具。开发者使用 memory_profiler 库可以有效的定位到程序中占有内存最多的代码,以此找到程序运行的瓶颈。

pip 命令安装:
在这里插入图片描述

代码示例:

from memory_profiler import profile@profile
def Fibonacci():a, b = 0, 1i = 0while i < 100:print(b)a, b = b, a+bi += 1Fibonacci()

运行结果:
在这里插入图片描述

1.3、使用 line_profiler 库

和 memory_profiler 类似,line_profiler 也是 Python 的第三方库,是一个可以逐行参看代码运行耗时的分析工具。

代码示例:

from line_profiler import LineProfilerdef Fibonacci():a, b = 0, 1i = 0while i < 100:print(b)a, b = b, a+bi += 1lp = LineProfiler() 
lp_wrap = lp(Fibonacci)
lp_wrap() # 输出统计数据
lp.print_stats()

运行结果:
在这里插入图片描述

接下来就开始介绍提升 Python 代码性能的六个技巧。

2、使用内置函数和库

Python 的内置函数和库与我们常用的自定义函数、自定义数据类型相比,运行速度会显得非常快。这主要是因为内置数据类型的底层是使用 C 语言实现的,而 C 语言又是目前为止执行效率最高的高级语言,这是使用 Python 所无法比较的。而且 Python 的开发团队也对这些内置函数和库进行了良好的测试和优化。

示例代码:

my_list = []
word_list = "hello,world"for word in word_list:my_list.append(word.upper())print(my_list)

更好的方法:

word_list = "hello,world"# 使用内置map函数
my_list = map(str.upper, word_list)print(list(my_list))

3、使用内插字符串 f-string

在 Python 程序中,使用支持插值的 f-string 取代 C 风格的格式字符串与 str.format 方法,会使得字符串操作效率得到提高。根据《Effective Python》一书中的介绍, 使用 f-string 是个简洁而强大的机制,它在简洁性、可读性和速度方面都比其他构建字符串的方式要更好。

示例代码:

places = 3
number = 1.23456my_str = "number值和places值分别为{0}和{1}".format(number, places)print(my_str)

更好的方法:

places = 3
number = 1.23456my_str = f"number值和places值分别为{number}{places}"print(my_str)

4、使用列表推导式

在小片段的 Python 代码中,使用列表推导式代替循环语句可以使得代码更加简洁易读;在大型项目中,相较于使用循环语句,使用列表推导式的执行效率也会更高。这是因为列表推导式是直接在 C 语言的环境下运行的,所以速度更快,而循环语句的解析执行往往比列表推导式的步骤更多,所以速度就更慢。

示例代码:

my_list = [] # 计算1到100以内的奇数
for i in range(1, 100): if i % 2 == 1:my_list.append(i)print(my_list)

更好的方法:

my_list = [i for i in range(1, 100) if i % 2 == 1]print(my_list)

5、使用 lru_cache 装饰器缓存数据

将程序执行时的信息存储在缓存中可以使程序运行的更加高效。在 Python 中也可以导入functools 库中的 lru_cache 装饰器来实现缓存操作,该操作会在内存中存储特定类的缓存,以此来达到程序更快的驱动速度。

示例代码:

import time def my_func(x):time.sleep(2)       # 模拟程序执行时间return x print(my_func(1)) 
print("=========")
print(my_func(1))       

更好的方法:

import functools
import time # 最多缓存128个不同的结果
@functools.lru_cache(maxsize=2)
def my_func(x):time.sleep(2)       # 模拟程序执行时间return x print(my_func(1)) 
print("=========")
print(my_func(1))       # 结果已被缓存,无需等待立即返回

6、针对循环结构的优化

在通常情况下,循环语句在程序中的执行总是会占据大量时间。因此我们开发 Python 程序时都会强调优化其中的循环结构,比方说避免在一个循环中使用点操作符和不必要的重复操作等。

示例代码:

my_list = []    
word_list = ["hello,", "word"]for word in word_list:  new_str = str.lower(word)        # 不必要的重复操作和点运算符my_list.append(new_str)print(my_list)

更好的方法:

my_list = []
word_list = ["hello,", "word"]
lower = str.lowerfor word in word_list:my_list.append(lower(word))print(my_list)

7、选择合适算法和数据结构

提到代码的运行效率,就不得不提到算法和数据结构能力了。 算法也就是程序解决问题的步骤,而数据结构是指数据的存储和组织。选择合适的算法和数据结构,可以在很大程度上提升 Python 代码的运行效率。

示例代码:

# 在有序数组中,使用二分查找算法查找元素要比使用顺序查找算法效率更高
def sequential_search(nums,target):for num in nums:if num == target:return nums.index(num)return -1			# 返回-1表示没有找到目标元素nums = [1, 8, 10, 11, 22]
target = 11
print(sequential_search(nums, target))

更好的方法:

# 二分查找
def binary_search(nums,target):first,last = 0, len(nums) - 1           # 定义数组的第一个元素下标和最后一个元素下标while first <= last:                    #左闭右闭区间mid_index = (first + last) // 2     #中间元素的下标值if nums[mid_index] < target:  first = mid_index + 1elif nums[mid_index] > target:last = mid_index - 1else:return mid_index     return -1nums = [1, 8, 10, 11, 22]
target = 11
print(binary_search(nums, target))

8、推荐书籍

在文章的最后,为了能够让大家编写高质量的 Python 代码,推荐给大家一本书叫 《Effective Python》,书中讲的是编写高质量 Python 代码的90个有效方法。

在这里插入图片描述


结语

🎪 以上就是提升 Python 代码性能的技巧介绍啦,希望对大家有所帮助。感谢大家的支持。

相关文章:

提升Python代码性能的六个技巧

文章目录前言为什么要写本文&#xff1f;1、代码性能检测1.1、使用 timeit 库1.2、使用 memory_profiler 库1.3、使用 line_profiler 库2、使用内置函数和库3、使用内插字符串 f-string4、使用列表推导式5、使用 lru_cache 装饰器缓存数据6、针对循环结构的优化7、选择合适算法…...

VI的常用命令

VI的常用命令 文章目录VI的常用命令vi/vim是什么&#xff1f;VI普通模式命令VI编辑模式命令VI指令模式vi/vim是什么&#xff1f; VI是Unix操作系统和类Unix操作系统中最通用的文本编辑器 VIM编辑器是从VI发展出来的一个性能更强大的文本编辑器。可以主动的将字体颜色辨别语法…...

【数据结构】万字深入浅出讲解单链表(附原码 | 超详解)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;C语言实现数据结构 &#x1f4ac;总结&#xff1a;希望你看完…...

无线WiFi安全渗透与攻防(五)之aircrack-ng破解WEP加密

系列文章 无线WiFi安全渗透与攻防(一)之无线安全环境搭建 无线WiFi安全渗透与攻防(二)之打造专属字典 无线WiFi安全渗透与攻防(三)之Windows扫描wifi和破解WiFi密码 无线WiFi安全渗透与攻防(四)之kismet的使用 aircrack-ng破解WEP加密 1.WEP介绍 其实我们平常在使用wifi的时…...

MySQL中事务的相关问题

事务 一、事务的概述&#xff1a; 1、事务处理&#xff08;事务操作&#xff09;&#xff1a;保证所有事务都作为一个工作单元来执行&#xff0c;即使出现了故障&#xff0c;都不能改变这种执行方式。当在一个事务中执行多个操作时&#xff0c;要么所有的事务都被提交(commit…...

推荐算法再次踩坑记录

去年搞通了EasyRec这个玩意&#xff0c;没想到今年还要用推荐方面的东西&#xff0c;行吧&#xff0c;再来一次&#xff0c;再次踩坑试试。1、EasyRec训练测试数据下载&#xff1a;git clone后&#xff0c;进入EasyRec&#xff0c;然后执行&#xff1a;bash scripts/init.sh 将…...

STM32 (十五)MPU6050

简介前言一、MPU6050简介MPU6050是一款性价比很高的陀螺仪&#xff0c;可以读取X Y Z 三轴角度&#xff0c;X Y Z 三轴加速度&#xff0c;还有内置的温度传感器&#xff0c;在姿态解析方面应用非常广泛。下面是它在淘宝上的参数图产品尺寸产品参数产品原理图&#xff1a;二、硬…...

使用yarn,依赖报各种错误怎么办

使用 yarn^3.x 版本时&#xff0c;默认并不会安装包到 node_modules&#xff0c;因为 yarn3.x 是即插即用的&#xff0c;也就是说如果你下载过这个包&#xff0c;yarn只会生成一个 Png文件&#xff0c;然后将包的路径 link 到下载过的地方&#xff0c;这样可以省去很多时间。而…...

面试官:rem和vw有什么区别

"rem" 和 "vw"的区别 "rem" 和 "vw" 都是用于网页设计的CSS单位。 "rem" 是相对于根元素的字体大小来计算的单位&#xff0c;即相对于 "html" 标签的字体大小。例如&#xff0c;如果 "html" 标签的字…...

【GPT-4】GPT-4 相关内容总结

目录 ​编辑 官网介绍 GPT-4 内容提升总结 GPT-4 简短版总结 GPT-4 基础能力 GPT-4 图像处理 GPT-4 技术报告 训练过程 局限性 GPT-4 风险和应对措施 开源项目&#xff1a;OpenAI Evals 申请 GPT-4 API API的介绍以及获取 官网介绍 官网&#xff1a;GPT-4 API候…...

5.springcloud微服务架构搭建 之 《springboot集成Hystrix》

1.springcloud微服务架构搭建 之 《springboot自动装配Redis》 2.springcloud微服务架构搭建 之 《springboot集成nacos注册中心》 3.springcloud微服务架构搭建 之 《springboot自动装配ribbon》 4.springcloud微服务架构搭建 之 《springboot集成openFeign》 目录 1.项目…...

【工作中问题解决实践 七】SpringBoot集成Jackson进行对象序列化和反序列化

去年10月份以来由于公司和家里的事情太多&#xff0c;所以一直没有学习&#xff0c;最近缓过来了&#xff0c;学习的脚步不能停滞啊。回归正题&#xff0c;其实前年在学习springMvc的时候也学习过Jackson【Spring MVC学习笔记 五】SpringMVC框架整合Jackson工具&#xff0c;但是…...

香港服务器遭受DDoS攻击后如何恢复运行?

​  您是否发现流量异常上升?您的网站突然崩溃了吗?当您注意到这些迹象时&#xff0c;可能是在陷入了DDoS攻击的困境&#xff0c;因而&#xff0c;当开始考虑使用香港服务器时&#xff0c;也应该考虑香港服务器设备受DDoS攻击时&#xff0c;如何从中恢复。 在 DDoS 攻击香港…...

【Hive】配置

目录 Hive参数配置方式 参数的配置方式 1. 文件配置 2. 命令行参数配置 3. 参数声明配置 配置源数据库 配置元数据到MySQL 查看MySQL中的元数据 Hive服务部署 hiveserver2服务 介绍 部署 启动 远程连接 1. 使用命令行客户端beeline进行远程访问 metastore服务 …...

IP-GUARD如何强制管控电脑设置开机密码要符合密码复杂度?

如何强制管控电脑设置开机密码要符合密码复杂度? 7 可以在控制台-【策略】-【定制配置】,添加一条配置,开启系统密码复杂度检测。 类别:自定义 关键字:bp_password_complexity 内容:1 效果图:...

剑指 Offer II 031. 最近最少使用缓存

题目链接 剑指 Offer II 031. 最近最少使用缓存 mid 题目描述 运用所掌握的数据结构&#xff0c;设计和实现一个 LRU(Least Recently Used&#xff0c;最近最少使用) 缓存机制 。 实现 LRUCache类&#xff1a; LRUCache(int capacity)以正整数作为容量 capacity初始化 LRU缓…...

44岁了,我从没想过在CSDN创作2年,会有这么大收获

1998年上的大学&#xff0c;02年毕业&#xff0c;就算从工作算起&#xff0c;我也有20余年的码龄生涯了。 但正式开启博文的写作&#xff0c;却是2021年开始的&#xff0c;差不多也就写了2年的博客&#xff0c;今天我来说说我在CSDN的感受和收获。 我是真的没想到&#xff0c;…...

相位相参信号源的设计--示波器上的信号不稳定,来回跑?

目录乱跑的波形边沿触发触发方式外部触发相参与非相参相位相参的射频信号源样机外观与内部设计软件设计上位机软件信号源使用方法PWM触发信号射频信号的时域波形射频信号的频谱输出功率在示波器的实际使用当中波形在示波器的时域上乱跑&#xff0c;左右移动&#xff0c;定不下来…...

Spring Boot 整合 RabbitMQ 多种消息模式

Spring Boot 整合 RabbitMQ 多种消息模式 准备工作集成 RabbitMQ发布/订阅模式点对点模式主题模式总结Spring Boot 是一个流行的 Java 应用程序开发框架,而 RabbitMQ 是一款可靠的消息队列软件。将 Spring Boot 和 RabbitMQ 结合起来可以帮助我们轻松地实现异步消息传递。Rabb…...

node多版本控制

前言 最近在折腾Python&#xff0c;并将node升级至v18.14.2。突然发现一个旧项目无法运行&#xff0c;也无法打包&#xff0c;里面的node-sass报错&#xff0c;显然这是因为node版本过高导致的。 将node版本降低至以前的v14.16.0&#xff0c;果然立马就能正常运行。 存在不同…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...