zoukankan      html  css  js  c++  java
  • Python学习笔记:6个代码性能坏习惯

    一、背景

    实现一个数据要求往往有多种不同的方式,殊途同归,但终究速度上仍有一定的差异。

    二、坏习惯

    1.不要导入根目录

    无论是内置模块,还是第三方模块,使用之前都必须导入。

    如果我们只是需要其中某几个函数,单独导入即可。

    ## 较慢
    import math
    %%timeit
    math.sqrt(100)
    # 171 ns ± 16.5 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
    
    ## 较快
    from math import sqrt
    %%timeit
    sqrt(100)
    # 120 ns ± 6.34 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
    

    2.避免使用点/点链

    访问对象的属性或者函数时,使用 dot 非常直观,但避免使用性能可能更佳。

    # 追加一个元素、然后删除元素
    my_list = [1,2,3]
    
    ## 较慢
    %%timeit
    my_list.append(4)
    my_list.remove(4)
    # 306 ns ± 38.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    ## 较快
    append = my_list.append
    remove = my_list.remove
    %%timeit
    append(4)
    remove(4)
    # 189 ns ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
    

    语法上有点不直观,但是如果我们重复删除数百万次的话,可以考虑使用该技巧。

    需要平衡代码的性能和可读性。

    3.不要使用“+”连接字符串

    字符串在 python 中是不可变的。

    当使用“+”进行拼接操作时,每个子字符串都是单独操作的。

    strs = ['Life', 'is', 'short', ',', 'I', 'FUCK']
    
    ## 较慢
    def join_strs(strs):
        result = ''
        for s in strs:
            result += ' ' + s  # result = result + ' ' + s
        return result[1:] # 删除第一位空格
    %%timeit
    join_strs(strs) # 'Life is short , I FUCK'
    # 1.23 µs ± 59.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    ## 较快
    def join_strs_better(strs):
        return ' '.join(strs)
    %%timeit
    join_strs_better(strs)
    # 327 ns ± 55.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    对于每个子字符串,都需要申请一个内存地址,然后将它与原始字符串进行连接,这成为一种很奢侈的开销。

    join() 函数事先知道所有子字符串,按最合适方式分配地址空间。

    4.不要使用临时变量进行值交换

    Python 内置语法支持值交换。

    ## 较慢
    %%timeit
    a = 1
    b = 2
    temp = a
    a = b
    b = temp
    # 72.1 ns ± 7.31 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
    
    ## 较快
    %%timeit
    a = 1
    b = 2
    a, b = b, a
    # 65.8 ns ± 8.37 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
    

    5.使用 if-condition 短路

    "短路"评估存在于许多编程语言中,Python 也是如此。

    基本上,它指的是某些布尔运算符的行为,其中仅当第一个参数不足以确定整个表达式的值时才执行或评估第二个参数。

    # 过滤列表:以C开头,大于30岁
    my_dict = [{'name': 'Alice', 'age': 28},
               {'name': 'Bob', 'age': 23},
               {'name': 'Chris', 'age': 33},
               {'name': 'Chelsea', 'age': 2},
               {'name': 'Carol', 'age': 24}]
    
    ## 较慢
    %%timeit
    filtered_list = []
    for person in my_dict:
        if person['name'].startswith('C') and person['age'] >= 30:
            filtered_list.append(person) 
    # 1.68 µs ± 45.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    ## 较快
    %%timeit
    filtered_list = []
    for person in my_dict:
        if person['age'] >= 30 and person['name'].startswith('C'):
            filtered_list.append(person)
    # 973 ns ± 57.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) 
    

    在知道数据大概分布的情况下,可以通过设置过滤条件前后,控制过滤速度。

    6.尽量使用for循环 避免使用while循环

    Python 使用很多 CPython 来提高性能。

    For Loop 具有相对较少的步骤,性能更好。

    ## 较慢
    %%timeit
    result = 0
    max_number = 10
    
    i = 0
    while i < max_number:
        result += i
        i += 1
    # 1.51 µs ± 63.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    ## 较快
    %%timeit
    result = 0
    max_number = 10
    
    for i in range(max_number):
        result += i
    # 1.04 µs ± 48.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    三、总结

    综合考虑性能、可读性、简洁性,对代码进行评审。

    参考链接:中枪了吧?六种让你的 Python 程序变慢的坏习惯

  • 相关阅读:
    mysql------Windows7 64bit安装教程------下载mysql
    [org.springframework.context.annotation.ComponentScanBeanDefinitionParser] are only available on JDK 1.5 and higher 问题--MyEclipse设置JDK版本
    码云Gitee上新建项目教程
    远程桌面无法复制粘贴
    Submine Text3格式化HTML/CSS/JS代码
    FTP上传文件,报错java.net.SocketException: Software caused connection abort: recv failed
    在MyEclipse使用Git新建分支,并上传分支---图文教程
    使用Git Bash上传代码到新的分支
    使用Git Bash从Git上下载代码到本地以及上传代码到码云Git
    安装Git Bash图文教程
  • 原文地址:https://www.cnblogs.com/hider/p/15783777.html
Copyright © 2011-2022 走看看