python基础代码技巧_Python 代码优化技巧(二)

Python 是一种脚本语言,相比 C/C++ 这样的编译语言,在效率和性能方面存在一些不足,但是可以通过代码调整来提高代码的执行效率。本文整理一些代码优化技巧。

代码优化基本原则代码正常运行后优化。

很多人一开始写代码就奔着性能优化的目标,“让正确的程序更快要比让快速的程序正确容易得多”,因此,优化的前提是代码能正常工作。过早地进行优化可能会忽视对总体性能指标的把握,在得到全局结果前不要主次颠倒。

权衡优化的代价。

优化是有代价的,想解决所有性能的问题是几乎不可能的。通常面临的选择是时间换空间或空间换时间。另外,开发代价也需要考虑。

优化关键耗时部分。

如果对代码的每一部分都去优化,这些修改会使代码难以阅读和理解。如果你的代码运行速度很慢,首先要找到代码运行慢的位置,通常是内部循环,专注于运行慢的地方进行优化。在其他地方,一点时间上的损失没有什么影响。

优化技巧

避免全局变量

在函数中编写代码而不要将其写为全局变量。 由于全局变量和局部变量实现方式不同,定义在全局范围内的代码运行速度会比定义在函数中的慢不少。通过将脚本语句放入到函数中,通常可带来 15% - 30% 的速度提升。

# 不推荐写法

import math

size = 10000

for x in range(size):

for y in range(size):

z = math.sqrt(x) + math.sqrt(y)

# 推荐写法

import math

def main(): # 定义到函数中,以减少全部变量使用

size = 10000

for x in range(size):

for y in range(size):

z = math.sqrt(x) + math.sqrt(y)

main()

避免 .

避免模块和函数属性访问

每次使用.(属性访问操作符时)会触发特定的方法,如__getattribute__()和__getattr__(),这些方法会进行字典操作,因此会带来额外的时间开销。通过from import语句,可以消除属性访问。

# 不推荐写法

import math

def computeSqrt(size: int):

result = []

for i in range(size):

result.append(math.sqrt(i))

return result

def main():

size = 10000

for _ in range(size):

result = computeSqrt(size)

main()

# 推荐写法,第一次优化 . 模块属性访问

from math import sqrt

def computeSqrt(size: int):

result = []

for i in range(size):

result.append(sqrt(i)) # 避免math.sqrt的使用

return result

def main():

size = 10000

for _ in range(size):

result = computeSqrt(size)

main()

# 推荐写法,第二次优化局部变量 sqrt,局部变量访问比全局变量快。

import math

def computeSqrt(size: int):

result = []

sqrt = math.sqrt # 赋值给局部变量

for i in range(size):

result.append(sqrt(i)) # 避免math.sqrt的使用

return result

def main():

size = 10000

for _ in range(size):

result = computeSqrt(size)

main()

# 推荐写法, 第三次优化函数属性 list.append() 方法

import math

def computeSqrt(size: int):

result = []

append = result.append

sqrt = math.sqrt # 赋值给局部变量

for i in range(size):

append(sqrt(i)) # 避免 result.append 和 math.sqrt 的使用

return result

def main():

size = 10000

for _ in range(size):

result = computeSqrt(size)

main()

避免访问类内属性

避免 . 的原则也适用于类内属性,访问self._value的速度会比访问一个局部变量更慢一些。通过将需要频繁访问的类内属性赋值给一个局部变量,可以提升代码运行速度。

# 不推荐写法

import math

from typing import List

class DemoClass:

def __init__(self, value: int):

self._value = value

def computeSqrt(self, size: int) -> List[float]:

result = []

append = result.append

sqrt = math.sqrt

for _ in range(size):

append(sqrt(self._value))

return result

def main():

size = 10000

for _ in range(size):

demo_instance = DemoClass(size)

result = demo_instance.computeSqrt(size)

main()

# 推荐写法,将self._value 赋值给局部变量

import math

from typing import List

class DemoClass:

def __init__(self, value: int):

self._value = value

def computeSqrt(self, size: int) -> List[float]:

result = []

append = result.append

sqrt = math.sqrt

value = self._value

for _ in range(size):

append(sqrt(value)) # 避免 self._value 的使用

return result

def main():

size = 10000

for _ in range(size):

demo_instance = DemoClass(size)

demo_instance.computeSqrt(size)

main()

避免不必要的抽象

任何时候当你使用额外的处理层(比如装饰器、属性访问、描述器)去包装代码时,都会让代码变慢。大部分情况下,需要重新进行审视使用属性访问器的定义是否有必要,使用getter/setter函数对属性进行访问通常是 C/C++ 程序员遗留下来的代码风格。如果真的没有必要,就使用简单属性。

# 不推荐写法。

class DemoClass:

def __init__(self, value: int):

self.value = value

@property

def value(self) -> int:

return self._value

@value.setter

def value(self, x: int):

self._value = x

def main():

size = 1000000

for i in range(size):

demo_instance = DemoClass(size)

value = demo_instance.value

demo_instance.value = i

main()

避免数据复制避免无意义的数据复制

交换值时不使用中间变量

a, b = b, a

字符串拼接使用join而不是+

当使用a + b拼接字符串时,由于 Python 中字符串是不可变对象,其会申请一块内存空间,将a和b分别复制到该新申请的内存空间中。因此,如果要拼接 n 个字符串,会产生 n-1 个中间结果,每产生一个中间结果都需要申请和复制一次内存,严重影响运行效率。而使用join()拼接字符串时,会首先计算出需要申请的总的内存空间,然后一次性地申请所需内存,并将每个字符串元素复制到该内存中去。

# 不推荐写法

import string

from typing import List

def concatString(string_list: List[str]) -> str:

result = ''

for str_i in string_list:

result += str_i

return result

def main():

string_list = list(string.ascii_letters * 100)

for _ in range(10000):

result = concatString(string_list)

main()

# 推荐写法

import string

from typing import List

def concatString(string_list: List[str]) -> str:

return ''.join(string_list) # 使用 join 而不是 +

def main():

string_list = list(string.ascii_letters * 100)

for _ in range(10000):

result = concatString(string_list)

main()

利用 if 条件的短路特性

if 条件的短路特性是指对if a and b这样的语句, 当a为False时将直接返回,不再计算b;对于if a or b这样的语句,当a为True时将直接返回,不再计算b。因此, 为了节约运行时间,对于or语句,应该将值为True可能性比较高的变量写在or前,而and应该推后。

循环优化利用for代替while;这是由于Python中for循环比while循环更快;

利用隐式for循环代替显式for循环;例如隐式sum(range(10000));

减少内层循环计算;

使用numba.jit优化

使用合适的数据结构

Python 内置的数据结构如str, tuple, list, set, dict底层都是 C 实现的,速度非常快,自己实现新的数据结构想在性能上达到内置的速度几乎是不可能的。

联系作者

uxwPHF6emnscDR4vLy41jg7vHq6sNY4Pr27OyYdRaLUrDAAosCCyywwAILLAossMACCyywKLDAAgsssMCiwAILLLDAAosCCyywwAILLAossMACCyywKLDAAgsssMCiwAILLLDAAosCCyywwAILLAossMACCyywKLDAAgsssMCiwAILLLDAAosCCyywwAILLAossMACCyywKLDAAgsssMCiwAILLLDAAosCCyywwAILLAossMACCyywKLDAAgsssL6u+k+AAQCR9eHtLKvLfwAAAABJRU5ErkJggg==

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556517.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rpm 讲解

CentOS7主要有rpm和yum这两种包软件的管理。两种包的管理各有用处,其中主要区别是:YUM使用简单但需要联网,YUM会去网上的YUM包源去获取所需要的软件包。而RPM的需要的操作经度比较细,需要我们做的事情比较多。 软件包的安装和卸是…

java顺序表冒泡排序_冒泡排序就这么简单 - Java3y的个人空间 - OSCHINA - 中文开源技术交流社区...

冒泡排序就这么简单在我大一的时候自学c语言和数据结构,我当时就接触到了冒泡排序(当时使用的是C语言编写的)。现在大三了,想要在暑假找到一份实习的工作,又要回顾一下数据结构与算法的知识点了。排序对我们来说是一点也不陌生了,…

python 多线程和协程结合_如何让 python 处理速度翻倍?内含代码

阿里妹导读:作为在日常开发生产中非常实用的语言,有必要掌握一些python用法,比如爬虫、网络请求等场景,很是实用。但python是单线程的,如何提高python的处理速度,是一个很重要的问题,这个问题的…

python批量生成图_利用Python批量生成任意尺寸的图片

实现效果 通过源图片,在当前工作目录的/img目录下生成1000张,分别从1*1到1000*1000像素的图片。 效果如下:目录结构 实现示例 # -*- coding: utf-8 -*- import threading from PIL import Image image_size range(1, 1001) def start(): for…

Mysql 如果有多个可选条件怎么加索引_MySQL|mysql-索引

1、索引是什么 1.1索引简介 索引是表的目录,是数据库中专门用于帮助用户快速查询数据的一种数据结构。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,以及快速定位查询数据。对于索引,会保存在额外的文件…

java 全双工服务器_利用Java实现串口全双工通讯_JAVA实例教程_IT部落

本文介绍了一个简单的通过串口实现全双工通讯的Java类库,该类库大大的简化了对串口进行操作的过程一个嵌入式系统通常需要通过串口与其主控系统进行全双工通讯,譬如一个流水线控制系统需要不断的接受从主控系统发送来的查询和控制信息,并将执…

python语言三大基本控制结构_Python基础(4) 控制结构

三种控制流语句:if、for、while,Python用缩进表明成块的代码,以四个空格表示隶属关系,所以语句不能随意缩进。 1 条件语句 (1)简单的if语句 a 10 if a > 0: #末尾带“:” print(这是一个整数…

Spring-bean的循环依赖以及解决方式___Spring源码初探--Bean的初始化-循环依赖的解决

本文主要是分析Spring bean的循环依赖,以及Spring的解决方式。 通过这种解决方式,我们可以应用在我们实际开发项目中。 什么是循环依赖?怎么检测循环依赖Spring怎么解决循环依赖Spring对于循环依赖无法解决的场景Spring解决循环依赖的方式我们…

java+cache使用方法_java相关:springboot使用GuavaCache做简单缓存处理的方法

java相关:springboot使用GuavaCache做简单缓存处理的方法发布于 2020-3-29|复制链接摘记: 问题背景实际项目碰到一个上游服务商接口有10秒的查询限制(同个账号)。项目中有一个需求是要实时统计一些数据,一个应用下可能有多个相同的账号。由于服务商接口的…

python程序设计方法_Python程序设计现代方法

章Python概述001 1.1计算机与计算机语言002 1.1.1计算机的诞生与发展002 1.1.2计算机语言概述006 1.1.3翻译执行008 1.2Python语言概述009 1.2.1Python语言发展史009 1.2.2Python语言的特点011 1.2.3Python的应用领域012 1.2.4Python版本的区别012 1.3Python环境配置014 1.3.1安…

Spring中bean的作用域与生命周期

在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。而bean的定义以及bea…

pat乙级 1014 java_pat乙级1014 福尔摩斯的约会

大侦探福尔摩斯接到一张奇怪的字条:“我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsbs&hgsfdk d&Hyscvnm”。大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间“星期四14:04”,因为前面两字符串中第1对相同的大…

python科学编程入门书_Python数据科学零基础一本通

领取成功 您已领取成功! 您可以进入Android/iOS/Kindle平台的多看阅读客户端,刷新个人中心的已购列表,即可下载图书,享受精品阅读时光啦! - | 回复不要太快哦~ 回复内容不能为空哦 回复已提交审核... 快登录帐号来一起…

python 整合excel_python EXcel表整合(自动办公)

收到任务,方便领导快速查看每个人的日程安排。比如每个工程师都有一个自己的表格记录自己的日程安排,领导查看每个人的日程安排需要一一打开所有工程师的日程安排表才能知道每个人的信息,而且非常不直观。 这里介绍下利用python解决实际办公问…

java poi 打开 保存_Java-Apache POI-在DB中读取和存储RTF内容

我们在Java应用程序中有一个新要求,即用户可以上传excel文件.excel文件中的一列将使用粗体,斜体,项目符号,彩色文本等格式.我们需要读取此excel文件并将这些值存储在Oracle DB表中.随后,我们还需要提取这些数据,并保留格式并下载到excel工作表中.我们计划将Apache-poi用于相同的…

Spring循环依赖的三种方式

引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错。下面说一下Spring是如果解决循环依赖的。 第一种:构造器参数循环依赖 Spring容…

python字典统计排序1_python-如何按字典顺序对Counter.mostCommon(n)的...

这里的问题是Counter dict是无序的,并且most_common不在乎键.为此,您需要对字典中的项目进行排序,然后提取最常见的3个项目. counter Counter(abcdef) most_common sorted(counter.items(), keylambda pair: (-pair[1], pair[0])) 这将首先对-pair [1](计数)进行排序.由于出现…

Java最后_Java最后一次总结

前言:最开始我学习了java如何简单编写一小段代码,发现java代码和C语言还是有很多相似的地方,到类与对象之后等等的很多的内容,我觉得还是有很大区别的,java对于c语言来说,显得更为高级及方便,让…

Spring 是如何解决循环依赖的?

1.由同事抛的一个问题开始 最近项目组的一个同事遇到了一个问题,问我的意见,一下子引起的我的兴趣,因为这个问题我也是第一次遇到。平时自认为对spring循环依赖问题还是比较了解的,直到遇到这个和后面的几个问题后,重…

python3自动化软件发布系统_基于python3做C/S端自动化测试可能用到的工具(不断更新中。。。。)...

选择一个合适的框架(库) (1)如果你的c/s端工具界面控件可以被捕获,则可以使用pyautoit,和pywinauto这2个库,附上界面元素捕获小工具(链接:https://pan.baidu.com/s/1_5--ZWsV-oS7r2ORwX7M7g 提取码:o4z5 ) (2)如果界面控件不可以…