掌握这9个技巧,让Python代码快如闪电(下)

9个使Python代码更快的微妙技巧。

微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩

图片

图片

图片来自Wallhaven

5. 更快的循环:优先使用局部变量

在Python中,访问局部变量比访问全局变量或对象的属性更快。

以下是一个实例来证明这一点:

import timeit


class Example:
    def __init__(self):
        self.value = 0


obj = Example()


def test_dot_notation():
    for _ in range(1000):
        obj.value += 1


def test_local_variable():
    value = obj.value
    for _ in range(1000):
        value += 1
    obj.value = value


print(timeit.timeit(test_dot_notation, number=1000))
# 0.036605041939765215
print(timeit.timeit(test_local_variable, number=1000))
# 0.024470250005833805

这就是Python的工作原理。直观地说,当一个函数被编译时,其中的局部变量是已知的,但其他外部变量需要时间来检索。

这可能是一个小问题,但是当处理大量数据时,我们可以利用它来优化我们的代码。

6. 更快的执行速度:优先使用内置模块和库

当工程师们说到Python时,默认情况下指的是CPython。因为CPython是Python语言的默认实现,也是使用最广泛的实现。

鉴于它的大部分内置模块和库都是用C语言编写的,而C语言是一种更快且更底层的语言,因此我们应该利用这些内置模块和库,避免重复劳动。

import timeit
import random
from collections import Counter


def count_frequency_custom(lst):
    frequency = {}
    for item in lst:
        if item in frequency:
            frequency[item] += 1
        else:
            frequency[item] = 1
    return frequency


def count_frequency_builtin(lst):
    return Counter(lst)


large_list = [random.randint(0, 100) for _ in range(1000)]

print(timeit.timeit(lambda: count_frequency_custom(large_list), number=100))
# 0.005160166998393834
print(timeit.timeit(lambda: count_frequency_builtin(large_list), number=100))
# 0.002444291952997446

上面的程序比较了两种统计列表中元素频率的方法。可以看到,利用collections模块中内置的Counter函数比自己编写的for循环更快、更简洁、更好。

7. 更快的函数调用:利用缓存装饰器轻松实现记忆化

缓存是一种常用的技术,用于避免重复计算并加快程序的运行速度。

幸运的是,在大多数情况下,我们不需要自己编写缓存处理代码,因为Python为此提供了一个开箱即用的装饰器来实现这个目的——@functools.cache

例如,下面的代码将执行两个生成斐波那契数的函数,一个有缓存装饰器,而另一个没有:

import timeit
import functools


def fibonacci(n):
    if n in (0, 1):
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)


@functools.cache
def fibonacci_cached(n):
    if n in (0, 1):
        return n
    return fibonacci_cached(n - 1) + fibonacci_cached(n - 2)


# 测试每个函数的执行时间
print(timeit.timeit(lambda: fibonacci(30), number=1))
# 0.09499712497927248
print(timeit.timeit(lambda: fibonacci_cached(30), number=1))
# 6.458023563027382e-06

结果证明了@functools.cache装饰器是如何使我们的代码变得更快的。

基本的fibonacci函数效率较低,因为在计算fibonacci(30)结果的过程中,它会多次重新计算相同的斐波那契数。

而使用缓存的版本要快得多,因为它缓存了之前的计算结果。因此,它只计算每个斐波那契数一次,并且对于相同的参数再次调用时会从缓存中获取结果。

仅仅添加一个内置的装饰器就可以带来如此大的改进,这就是Pythonic的意义所在。😎

8. 更快的无限循环:优先使用"while 1"而不是"while True"

要创建一个无限的while循环,我们可以使用while Truewhile 1

它们的性能差异通常可以忽略不计。但是,了解while 1稍微快一些还是很有趣的。

这源于1是一个字面常量,而True是Python全局作用域中需要查找的一个全局名称,因此需要一点点额外开销。

让我们在代码片段中进一步比较这两种方式的真实性能:

import timeit


def loop_with_true():
    i = 0
    while True:
        if i >= 1000:
            break
        i += 1


def loop_with_one():
    i = 0
    while 1:
        if i >= 1000:
            break
        i += 1


print(timeit.timeit(loop_with_true, number=10000))
# 0.1733035419601947
print(timeit.timeit(loop_with_one, number=10000))
# 0.16412191605195403

正如所看到的,while 1的速度确实稍快一些。

然而,现代的Python解释器(如CPython)已经过高度优化,这种差异通常是微不足道的。所以不需要担心这种可忽略的差异。更不用说while Truewhile 1更易读了。

9. 更快的启动:巧妙地导入Python模块

在Python脚本的顶部导入所有模块似乎是很自然的。

实际上,我们并不需要这样做。

而且,如果一个模块太大,在需要时导入它是一个更好的选择。

def my_function():
    import heavy_module
    # 函数的其余部分

以上代码中,heavy_module是在函数内部导入的。这是一种“延迟加载”的思想,即延迟到在调用my_function时才进行导入。

这种方法的好处是,如果在执行脚本的过程中从未调用过my_function,那么heavy_module就不会被加载,从而节省资源并减少脚本的启动时间。

结语

综上所述,就是9个优化Python代码性能的实用技巧,但在实际应用时需要根据具体情况进行权衡和调整。通过综合考虑代码的性能、可读性和可维护性,进而编写出高效且易于理解的Python代码。

推荐书单

《Python从入门到精通(第3版)》

《Python从入门到精通(第3版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Python进行程序开发应该掌握的各方面技术。全书共分27章,包括初识Python、Python语言基础、运算符与表达式、流程控制语句、列表和元组、字典和集合、字符串、Python中使用正则表达式、函数、面向对象程序设计、模块、文件及目录操作、操作数据库、使用进程和线程、网络编程、异常处理及程序调试、Pygame游戏编程、推箱子游戏、网络爬虫开发、火车票分析助手、数据可视化、京东电商销售数据分析与预测、Web编程、Flask框架、e起去旅行网站、Python自动化办公、AI图像识别工具等内容。书中所有知识都结合具体实例进行介绍,涉及的程序代码都给出了详细的注释,读者可轻松领会Python程序开发的精髓,快速提升开发技能。

《Python从入门到精通(第3版)》icon-default.png?t=N7T8https://item.jd.com/14055900.html

 

精彩回顾

《数据科学必备的Python前端库Top-5》

《轻松上手,本地运行LlaMA 2的简易指南》

《8个Python开发者必备的PyCharm插件》

《数据科学不可或缺的10个Python库,让你事半功倍》

《掌握Python设计模式,SQL Alchemy助你打破ORM与模型类的束缚》

《Python进阶之路,2024年7个不可错过的技巧》

微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩

访问【IT今日热榜】,发现每日技术热点

相关推荐

  1. 掌握社交的二十心理技巧

    2024-01-30 17:28:01       10 阅读
  2. 初学python适合掌握的20技巧

    2024-01-30 17:28:01       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-30 17:28:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-30 17:28:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-30 17:28:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-30 17:28:01       20 阅读

热门阅读

  1. 【力扣经典面试题】27. 移除元素

    2024-01-30 17:28:01       40 阅读
  2. Spring JPA与Hibernate学习使用

    2024-01-30 17:28:01       38 阅读
  3. Oracle Extractor 软件下载

    2024-01-30 17:28:01       42 阅读
  4. git由SSH更改为HTTPS

    2024-01-30 17:28:01       32 阅读
  5. CSS transition(过渡效果)详解

    2024-01-30 17:28:01       35 阅读
  6. 【Rust】第七节:枚举与模式匹配

    2024-01-30 17:28:01       41 阅读
  7. Tensorflow2.x实现用于model.fit()中的医学图像dataset

    2024-01-30 17:28:01       26 阅读
  8. js读取json的固定数据的一种方法

    2024-01-30 17:28:01       36 阅读
  9. html表单添加默认创建时间

    2024-01-30 17:28:01       35 阅读