一文分析提升Python性能的10个智能技巧

作者:

文章目录
  • 在处理大规模数据集时,检查某个元素是否在集合中,使用列表通常效率较低。列表的成员测试(x in some_list)是线性时间复杂度(O(n)),意味着它需要逐个扫描元素。而集合(set)则通过哈希表实现,允许常数时间复杂度(O(1))的查找,效率大幅提升。 big_list = list(range(1000000)) big_set = set(big_list) start = time.time() print(999999 in big_list) print(f”List lookup: {time.time() – start:.6f}s”) start = time.time() print(999999 in big_set) print(f”Set lookup: {time.time() – start:.6f}s”) 时间测试结果: 列表查找:约 0.015 秒 集合查找:约 0.00002 秒 如果你的任务涉及到去重、输入验证或交叉引用等操作,集合会比列表更高效。
  • 复制大型对象(如列表、字典或数组)在时间和内存上都是开销巨大的。每次复制都会创建新的对象,这可能导致内存浪费和性能下降,尤其在处理大数据集时。尽量使用原地操作而不是复制对象,Python 的许多内置数据结构都提供了原地操作的方法(如 sort、append、update 等)。 numbers = list(range(1000000)) def modify_list(lst): lst[0] = 999 return lst start = time.time() result = modify_list(numbers) print(f”In-place: {time.time() – start:.4f}s”) def copy_list(lst): new_lst = lst.copy() new_lst[0] = 999 return new_lst start = time.time() result = copy_list(numbers) print(f”Copy: {time.time() – start:.4f}s”) 时间测试结果: 原地修改:约 0.0001 秒 复制修改:约 0.0100 秒
  • Python 类的实例属性通常存储在动态字典(__dict__)中,这为灵活性提供了便利,但也带来了内存开销。通过使用 __slots__,可以显式声明固定的属性集合,避免创建 __dict__,从而节省内存。 class Point: __slots__ = (‘x’, ‘y’) def __init__(self, x, y): self.x = x self.y = y start = time.time() points = [Point(i, i+1) for i in range(1000000)] print(f”With slots: {time.time() – start:.4f}s”) 时间测试结果: 使用 __slots__:约 0.1200 秒 不使用 __slots__:约 0.1500 秒
  • Python 的 math 模块提供了一些内建的函数,这些函数是用 C 实现的,比直接在 Python 中实现的运算符更加高效。例如,使用 math.sqrt() 通常比使用 ** 0.5 运算符来计算平方根要更快。 import math numbers = list(range(10000000)) start = time.time() roots = [math.sqrt(n) for n in numbers] print(f”Math sqrt: {time.time() – start:.4f}s”) start = time.time() roots = [n ** 0.5 for n in numbers] print(f”Operator: {time.time() – start:.4f}s”) 时间测试结果: math.sqrt():约 0.2000 秒 ** 0.5:约 0.2500 秒
  • Python 在动态构建列表或数组时,会在后台进行扩容,每次扩容都会涉及到内存分配和数据复制。如果你知道数据结构的最终大小,预先分配内存能显著提高性能,避免反复扩容。 start = time.time() result = [0] * 1000000 for i in range(1000000): result[i] = i print(f”Pre-allocated: {time.time() – start:.4f}s”) start = time.time() result = [] for i in range(1000000): result.append(i) print(f”Dynamic: {time.time() – start:.4f}s”) 时间测试结果: 预分配:约 0.0300 秒 动态分配:约 0.0400 秒
  • 异常处理非常强大,但它的开销也不容小觑。尤其在性能关键的循环中,频繁的抛出和捕获异常会导致堆栈展开和上下文切换,这对性能有很大影响。在这些循环中,最好通过条件检查来避免预期之外的错误发生,而不是依赖异常处理。 numbers = list(range(10000000)) start = time.time() total = 0 for i in numbers: if i % 2 != 0: total += i // 2 else: total += i print(f”Conditional: {time.time() – start:.4f}s”) start = time.time() total = 0 for i in numbers: try: total += i / (i % 2) except ZeroDivisionError: total += i print(f”Exception: {time.time() – start:.4f}s”) 时间测试结果: 条件检查:约 0.3000 秒 异常处理:约 0.6000 秒
  • 在函数中反复使用同一段逻辑时,定义一个局部(嵌套)函数可以提高性能,因为 Python 会在局部作用域内更快地查找变量。 def outer(): def add_pair(a, b): return a + b result = 0 for i in range(10000000): result = add_pair(result, i) return result start = time.time() result = outer() print(f”Local function: {time.time() – start:.4f}s”) def add_pair(a, b): return a + b start = time.time() result = 0 for i in range(10000000): result = add_pair(result, i) print(f”Global function: {time.time() – start:.4f}s”) 时间测试结果: 局部函数:约 0.4000 秒 全局函数:约 0.4500 秒
  • Python 的 itertools 模块提供了一些高效的函数,适用于排列、组合、笛卡尔积等任务。这些函数采用惰性生成方式,能够在不占用大量内存的情况下处理大规模数据。 from itertools import product items = [1, 2, 3] * 10 start = time.time() result = list(product(items, repeat=2)) print(f”Itertools: {time.time() – start:.4f}s”) start = time.time() result = [] for x in items: for y in items: result.append((x, y)) print(f”Loops: {time.time() – start:.4f}s”) 时间测试结果: itertools.product():约 0.0005 秒 嵌套循环:约 0.0020 秒
  • 如果你需要在一个有序列表中进行查找或插入操作,使用 bisect 模块提供的二分查找方法会比手动实现的 线性查找更加高效。 import bisect sorted_list = list(range(1000000)) start = time.time() bisect.insort(sorted_list, 500000) print(f”Bisect insert: {time.time() – start:.4f}s”) start = time.time() sorted_list.append(500000) sorted_list.sort() print(f”Manual insert: {time.time() – start:.4f}s”) 时间测试结果: bisect.insort():约 0.1000 秒 手动插入:约 0.1500 秒
  • 对于数值计算密集型任务,numpy 是一种非常高效的解决方案。相比纯 Python 实现,numpy 通过优化的 C 代码和向量化操作,能大幅提升计算效率。 import numpy as np arr = np.arange(1000000) start = time.time() result = np.sqrt(arr) print(f”NumPy: {time.time() – start:.4f}s”) start = time.time() result = [x ** 0.5 for x in arr] print(f”List comprehension: {time.time() – start:.4f}s”) 时间测试结果: numpy.sqrt():约 0.2000 秒 列表推导:约 0.4500 秒
  • 掌握这些 Python 性能优化技巧,可以显著提升你的代码执行效率,特别是在处理大量数据或需要高性能计算时。通过了解和运用 Python 内置功能和高效的数据结构,不仅能提升运行速度,还能优化代码的可读性和可维护性。 到此这篇关于一文分析提升Python性能的10个智能技巧的文章就介绍到这了,更多相关Python性能提升技巧内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Python性能优化之让你的代码运行速度提升10倍的技巧分享 提升Python Web应用性能的10个关键技巧 pypy提升python项目性能使用详解 提升Python程序性能的7个习惯 python 性能提升的几种方法 浅析Python如何利用算法进行性能优化 5个Python性能优化技巧分享(代码提速300%)
  • 目录
    • 技巧 1:使用集合进行成员测试
    • 技巧 2:避免不必要的复制
    • 技巧 3:使用__slots__来提高内存效率
    • 技巧 4:使用math模块代替操作符
    • 技巧 5:预分配已知大小的内存
    • 技巧 6:避免在热循环中使用异常处理
    • 技巧 7:使用局部函数提高重复逻辑的效率
    • 技巧 8:使用itertools进行组合操作
    • 技巧 9:使用bisect进行有序列表操作
    • 技巧 10:使用numpy进行数值计算
    • 结语

    Python 作为一门高效、简洁且功能强大的编程语言,已经广泛应用于从 Web 开发到人工智能等多个领域。然而,随着项目的复杂性增加,性能瓶颈不可避免地浮现。尤其是在数据处理、实时系统和高性能计算方面,优化 Python 代码的执行效率变得至关重要。幸运的是,Python 提供了很多内置功能和优化技巧,可以显著提高代码的运行速度。

    以下是 10 个经过实践验证的性能优化策略,这些方法不依赖于外部库,而是通过高效的数据结构、低级优化和 Python 本身的内建功能来加速代码执行。通过这些技巧,你不仅可以在大数据集和计算密集型任务中获得性能提升,还能在保持代码简洁和可读性的同时,解决性能瓶颈。

    在处理大规模数据集时,检查某个元素是否在集合中,使用列表通常效率较低。列表的成员测试(x in some_list)是线性时间复杂度(O(n)),意味着它需要逐个扫描元素。而集合(set)则通过哈希表实现,允许常数时间复杂度(O(1))的查找,效率大幅提升。

    big_list = list(range(1000000))
    big_set = set(big_list)
    
    start = time.time()
    print(999999 in big_list)
    print(f"List lookup: {time.time() - start:.6f}s")
    
    start = time.time()
    print(999999 in big_set)
    print(f"Set lookup: {time.time() - start:.6f}s")
    

    时间测试结果:

    • 列表查找:约 0.015 秒
    • 集合查找:约 0.00002 秒

    如果你的任务涉及到去重、输入验证或交叉引用等操作,集合会比列表更高效。

    复制大型对象(如列表、字典或数组)在时间和内存上都是开销巨大的。每次复制都会创建新的对象,这可能导致内存浪费和性能下降,尤其在处理大数据集时。尽量使用原地操作而不是复制对象,Python 的许多内置数据结构都提供了原地操作的方法(如 sortappendupdate 等)。

    numbers = list(range(1000000))
    
    def modify_list(lst):
        lst[0] = 999
        return lst
    
    start = time.time()
    result = modify_list(numbers)
    print(f"In-place: {time.time() - start:.4f}s")
    
    def copy_list(lst):
        new_lst = lst.copy()
        new_lst[0] = 999
        return new_lst
    
    start = time.time()
    result = copy_list(numbers)
    print(f"Copy: {time.time() - start:.4f}s")
    

    时间测试结果:

    • 原地修改:约 0.0001 秒
    • 复制修改:约 0.0100 秒

    Python 类的实例属性通常存储在动态字典(__dict__)中,这为灵活性提供了便利,但也带来了内存开销。通过使用 __slots__,可以显式声明固定的属性集合,避免创建 __dict__,从而节省内存。

    class Point:
        __slots__ = ('x', 'y')
    
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
    start = time.time()
    points = [Point(i, i+1) for i in range(1000000)]
    print(f"With slots: {time.time() - start:.4f}s")
    

    时间测试结果:

    • 使用 __slots__:约 0.1200 秒
    • 不使用 __slots__:约 0.1500 秒

    Python 的 math 模块提供了一些内建的函数,这些函数是用 C 实现的,比直接在 Python 中实现的运算符更加高效。例如,使用 math.sqrt() 通常比使用 ** 0.5 运算符来计算平方根要更快。

    import math
    
    numbers = list(range(10000000))
    
    start = time.time()
    roots = [math.sqrt(n) for n in numbers]
    print(f"Math sqrt: {time.time() - start:.4f}s")
    
    start = time.time()
    roots = [n ** 0.5 for n in numbers]
    print(f"Operator: {time.time() - start:.4f}s")
    

    时间测试结果:

    • math.sqrt():约 0.2000 秒
    • ** 0.5:约 0.2500 秒

    Python 在动态构建列表或数组时,会在后台进行扩容,每次扩容都会涉及到内存分配和数据复制。如果你知道数据结构的最终大小,预先分配内存能显著提高性能,避免反复扩容。

    start = time.time()
    result = [0] * 1000000
    for i in range(1000000):
        result[i] = i
    print(f"Pre-allocated: {time.time() - start:.4f}s")
    
    start = time.time()
    result = []
    for i in range(1000000):
        result.append(i)
    print(f"Dynamic: {time.time() - start:.4f}s")
    

    时间测试结果:

    • 预分配:约 0.0300 秒
    • 动态分配:约 0.0400 秒

    异常处理非常强大,但它的开销也不容小觑。尤其在性能关键的循环中,频繁的抛出和捕获异常会导致堆栈展开和上下文切换,这对性能有很大影响。在这些循环中,最好通过条件检查来避免预期之外的错误发生,而不是依赖异常处理。

    numbers = list(range(10000000))
    
    start = time.time()
    total = 0
    for i in numbers:
        if i % 2 != 0:
            total += i // 2
        else:
            total += i
    print(f"Conditional: {time.time() - start:.4f}s")
    
    start = time.time()
    total = 0
    for i in numbers:
        try:
            total += i / (i % 2)
        except ZeroDivisionError:
            total += i
    print(f"Exception: {time.time() - start:.4f}s")
    

    时间测试结果:

    • 条件检查:约 0.3000 秒
    • 异常处理:约 0.6000 秒

    在函数中反复使用同一段逻辑时,定义一个局部(嵌套)函数可以提高性能,因为 Python 会在局部作用域内更快地查找变量。

    def outer():
        def add_pair(a, b):
            return a + b
    
        result = 0
        for i in range(10000000):
            result = add_pair(result, i)
    
        return result
    
    start = time.time()
    result = outer()
    print(f"Local function: {time.time() - start:.4f}s")
    
    def add_pair(a, b):
        return a + b
    
    start = time.time()
    result = 0
    for i in range(10000000):
        result = add_pair(result, i)
    print(f"Global function: {time.time() - start:.4f}s")
    

    时间测试结果:

    • 局部函数:约 0.4000 秒
    • 全局函数:约 0.4500 秒

    Python 的 itertools 模块提供了一些高效的函数,适用于排列、组合、笛卡尔积等任务。这些函数采用惰性生成方式,能够在不占用大量内存的情况下处理大规模数据。

    from itertools import product
    
    items = [1, 2, 3] * 10
    
    start = time.time()
    result = list(product(items, repeat=2))
    print(f"Itertools: {time.time() - start:.4f}s")
    
    start = time.time()
    result = []
    for x in items:
        for y in items:
            result.append((x, y))
    print(f"Loops: {time.time() - start:.4f}s")
    

    时间测试结果:

    • itertools.product():约 0.0005 秒
    • 嵌套循环:约 0.0020 秒

    如果你需要在一个有序列表中进行查找或插入操作,使用 bisect 模块提供的二分查找方法会比手动实现的

    线性查找更加高效。

    import bisect
    
    sorted_list = list(range(1000000))
    
    start = time.time()
    bisect.insort(sorted_list, 500000)
    print(f"Bisect insert: {time.time() - start:.4f}s")
    
    start = time.time()
    sorted_list.append(500000)
    sorted_list.sort()
    print(f"Manual insert: {time.time() - start:.4f}s")
    

    时间测试结果:

    • bisect.insort():约 0.1000 秒
    • 手动插入:约 0.1500 秒

    对于数值计算密集型任务,numpy 是一种非常高效的解决方案。相比纯 Python 实现,numpy 通过优化的 C 代码和向量化操作,能大幅提升计算效率。

    import numpy as np
    
    arr = np.arange(1000000)
    
    start = time.time()
    result = np.sqrt(arr)
    print(f"NumPy: {time.time() - start:.4f}s")
    
    start = time.time()
    result = [x ** 0.5 for x in arr]
    print(f"List comprehension: {time.time() - start:.4f}s")
    

    时间测试结果:

    • numpy.sqrt():约 0.2000 秒
    • 列表推导:约 0.4500 秒

    掌握这些 Python 性能优化技巧,可以显著提升你的代码执行效率,特别是在处理大量数据或需要高性能计算时。通过了解和运用 Python 内置功能和高效的数据结构,不仅能提升运行速度,还能优化代码的可读性和可维护性。

    到此这篇关于一文分析提升Python性能的10个智能技巧的文章就介绍到这了,更多相关Python性能提升技巧内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

    您可能感兴趣的文章:

    • Python性能优化之让你的代码运行速度提升10倍的技巧分享
    • 提升Python Web应用性能的10个关键技巧
    • pypy提升python项目性能使用详解
    • 提升Python程序性能的7个习惯
    • python 性能提升的几种方法
    • 浅析Python如何利用算法进行性能优化
    • 5个Python性能优化技巧分享(代码提速300%)

    站内搜索