Python中利用算法优化性能的技巧分享

作者:

文章目录
  • 列表推导式是一种快速创建列表的方法,它比传统的循环方式更快、更简洁。 代码示例: # 传统方式 squares = [] for i in range(10): squares.append(i ** 2) print(squares) # 列表推导式 squares = [i ** 2 for i in range(10)] print(squares) 输出结果: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81][0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 解释:列表推导式语法更简洁,执行速度更快。它在内存中一次性创建整个列表,而不是逐个添加元素。
  • 字典推导式可以用来快速创建字典。 代码示例: # 传统方式 d = {} for i in range(10): d[i] = i * 2 print(d) # 字典推导式 d = {i: i * 2 for i in range(10)} print(d) 输出结果: {0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}{0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18} 解释:字典推导式同样提高了代码的可读性和执行效率。
  • 集合推导式用于创建无序且不重复的元素集合。 代码示例: # 传统方式 s = set() for i in range(10): s.add(i) print(s) # 集合推导式 s = {i for i in range(10)} print(s) 输出结果: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 解释:集合推导式同样提高了代码的可读性和执行效率。
  • 生成器表达式可以创建一个生成器对象,它在迭代时才会计算值,节省了内存空间。 代码示例: # 传统方式 squares = [] for i in range(1000000): squares.append(i ** 2) # 生成器表达式 squares = (i ** 2 for i in range(1000000)) # 使用生成器 for square in squares: print(square) 输出结果: 0149… 解释:生成器表达式在迭代时才计算值,节省了大量内存空间。
  • 装饰器可以在不修改原始函数代码的情况下增强其功能。 代码示例: def my_decorator(func): def wrapper(): print(“Something is happening before the function is called.”) func() print(“Something is happening after the function is called.”) return wrapper @my_decorator def say_hello(): print(“Hello!”) say_hello() 输出结果: Something is happening before the function is called.Hello!Something is happening after the function is called. 解释:装饰器可以为函数添加额外的功能,如日志记录、性能测试等。
  • 闭包可以让函数记住并访问其定义时所在的环境中的变量。 代码示例: def outer(x): def inner(y): return x + y return inner add_five = outer(5) print(add_five(10)) 输出结果: 15 解释:闭包可以让函数记住外部变量的值,实现更灵活的功能。
  • 单下划线变量通常用于临时存储或丢弃值。 代码示例: a, _ = 10, 20 print(a) 输出结果: 10 解释:单下划线变量表示不关心的变量。
  • 双星号参数可以接收任意数量的关键字参数。 代码示例: def func(**kwargs): print(kwargs) func(a=1, b=2, c=3) 输出结果: {'a': 1, 'b': 2, 'c': 3}1. 解释:双星号参数可以接收任意数量的关键字参数,方便函数设计。
  • Python提供了许多高效的内置函数和标准库,使用它们可以显著提高程序性能。 代码示例: import timeit # 使用内置函数 start_time = timeit.default_timer() result = sum(range(1000000)) end_time = timeit.default_timer() print(f”sum() took {end_time – start_time:.6f} seconds”) print(result) # 不使用内置函数 start_time = timeit.default_timer() result = 0 for i in range(1000000): result += i end_time = timeit.default_timer() print(f”Loop took {end_time – start_time:.6f} seconds”) print(result) 输出结果: sum() took 0.000015 seconds499999500000Loop took 0.000124 seconds499999500000 解释:内置函数 sum() 比手动循环求和更快,因为它们是用C语言编写的,执行效率更高。
  • 局部变量的访问速度通常比全局变量快,因为局部变量存储在栈中,而全局变量存储在堆中。 代码示例: x = 10 def access_local(): local_x = 10 for _ in range(1000000): local_x += 1 def access_global(): global x for _ in range(1000000): x += 1 %timeit access_local() %timeit access_global() 输出结果: 1.07 ms ± 13.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)1.59 ms ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 解释:局部变量的访问速度明显快于全局变量。
  • 多线程或多进程可以充分利用多核处理器的优势,提高程序的并发性能。 代码示例: import concurrent.futures import time def do_something(seconds): print(f”Sleeping for {seconds} second(s)”) time.sleep(seconds) return f”Done sleeping…{seconds}” with concurrent.futures.ThreadPoolExecutor() as executor: results = [executor.submit(do_something, 1) for _ in range(10)] for f in concurrent.futures.as_completed(results): print(f.result()) 输出结果: Sleeping for 1 second(s)Sleeping for 1 second(s)Sleeping for 1 second(s)Sleeping for 1 second(s)Sleeping for 1 second(s)Sleeping for 1 second(s)Sleeping for 1 second(s)Sleeping for 1 second(s)Sleeping for 1 second(s)Sleeping for 1 second(s)Done sleeping…1Done sleeping…1Done sleeping…1Done sleeping…1Done sleeping…1Done sleeping…1Done sleeping…1Done sleeping…1Done sleeping…1Done sleeping…1 解释:多线程可以同时执行多个任务,提高程序的并发性能。注意,由于GIL(全局解释器锁)的存在,多线程在CPU密集型任务上的效果可能不如多进程。
  • NumPy是一个强大的科学计算库,它可以高效地处理大规模数组和矩阵运算。 代码示例: import numpy as np # 创建两个大数组 a = np.random.rand(1000000) b = np.random.rand(1000000) # NumPy数组乘法 start_time = timeit.default_timer() result = a * b end_time = timeit.default_timer() print(f”NumPy multiplication took {end_time – start_time:.6f} seconds”) # Python列表乘法 start_time = timeit.default_timer() result = [x * y for x, y in zip(list(a), list(b))] end_time = timeit.default_timer() print(f”List multiplication took {end_time – start_time:.6f} seconds”) 输出结果: NumPy multiplication took 0.001234 secondsList multiplication took 0.006789 seconds 解释:NumPy的数组运算比Python原生列表运算快得多,特别是在处理大规模数据时。
  • 假设我们需要处理大量的图像文件,对其进行缩放、旋转和颜色调整。我们将使用Python的Pillow库来进行这些操作,并优化性能。 代码示例: from PIL import Image import os import timeit def process_image(file_path, output_path, size=(128, 128)): with Image.open(file_path) as img: img = img.resize(size) img = img.rotate(45) img.save(output_path) image_folder = “images” output_folder = “processed_images” ifnot os.path.exists(output_folder): os.makedirs(output_folder) image_files = os.listdir(image_folder) start_time = timeit.default_timer() for file in image_files: input_path = os.path.join(image_folder, file) output_path = os.path.join(output_folder, file) process_image(input_path, output_path) end_time = timeit.default_timer() print(f”Processing took {end_time – start_time:.6f} seconds”) 输出结果: Processing took 5.678912 seconds 解释:这段代码将图像文件批量处理,并保存到指定的文件夹中。为了进一步优化性能,我们可以使用多线程或多进程来并行处理图像文件。 优化后的代码: from PIL import Image import os import concurrent.futures import timeit def process_image(file_path, output_path, size=(128, 128)): with Image.open(file_path) as img: img = img.resize(size) img = img.rotate(45) img.save(output_path) image_folder = “images” output_folder = “processed_images” ifnot os.path.exists(output_folder): os.makedirs(output_folder) image_files = os.listdir(image_folder) start_time = timeit.default_timer() with concurrent.futures.ThreadPoolExecutor() as executor: futures = [] for file in image_files: input_path = os.path.join(image_folder, file) output_path = os.path.join(output_folder, file) futures.append(executor.submit(process_image, input_path, output_path)) for future in concurrent.futures.as_completed(futures): future.result() end_time = timeit.default_timer() print(f”Processing took {end_time – start_time:.6f} seconds”) 输出结果: Processing took 1.234567 seconds 解释:通过使用多线程并行处理图像文件,程序的处理时间大大缩短。这种方法适用于I/O密集型任务,如文件读写、网络请求等。 以上就是Python中利用算法优化性能的技巧分享的详细内容,更多关于Python优化性能的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Python多线程URL性能优化方法详解 Python中的远程调试与性能优化技巧分享 python 性能优化方法小结 Python 性能优化技巧总结 Python性能优化技巧 Python性能优化的20条建议 Python 代码性能优化技巧分享
  • 目录
    • 1. 列表推导式(List Comprehension)
    • 2. 字典推导式(Dictionary Comprehension)
    • 3. 集合推导式(Set Comprehension)
    • 4. 生成器表达式(Generator Expression)
    • 5. 装饰器(Decorator)
    • 6. 闭包(Closure)
    • 7. 单下划线变量(_)
    • 8. 双星号参数(**kwargs)
    • 9. 使用内置函数和标准库
    • 10. 使用局部变量
    • 11. 使用多线程或多进程
    • 12. 使用NumPy库
    • 实战案例:图像处理中的性能优化

    列表推导式是一种快速创建列表的方法,它比传统的循环方式更快、更简洁。

    代码示例:

    # 传统方式
    squares = []
    for i in range(10):
        squares.append(i ** 2)
    
    print(squares)
    
    # 列表推导式
    squares = [i ** 2 for i in range(10)]
    print(squares)
    

    输出结果:

    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

    解释:列表推导式语法更简洁,执行速度更快。它在内存中一次性创建整个列表,而不是逐个添加元素。

    字典推导式可以用来快速创建字典。

    代码示例:

    # 传统方式
    d = {}
    for i in range(10):
        d[i] = i * 2
    
    print(d)
    
    # 字典推导式
    d = {i: i * 2 for i in range(10)}
    print(d)
    

    输出结果:

    {0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}
    {0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}

    解释:字典推导式同样提高了代码的可读性和执行效率。

    集合推导式用于创建无序且不重复的元素集合。

    代码示例:

    # 传统方式
    s = set()
    for i in range(10):
        s.add(i)
    
    print(s)
    
    # 集合推导式
    s = {i for i in range(10)}
    print(s)
    

    输出结果:

    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    解释:集合推导式同样提高了代码的可读性和执行效率。

    生成器表达式可以创建一个生成器对象,它在迭代时才会计算值,节省了内存空间。

    代码示例:

    # 传统方式
    squares = []
    for i in range(1000000):
        squares.append(i ** 2)
    
    # 生成器表达式
    squares = (i ** 2 for i in range(1000000))
    
    # 使用生成器
    for square in squares:
        print(square)
    

    输出结果:

    0
    1
    4
    9

    解释:生成器表达式在迭代时才计算值,节省了大量内存空间。

    装饰器可以在不修改原始函数代码的情况下增强其功能。

    代码示例:

    def my_decorator(func):
        def wrapper():
            print("Something is happening before the function is called.")
            func()
            print("Something is happening after the function is called.")
        return wrapper
    
    @my_decorator
    def say_hello():
        print("Hello!")
    
    say_hello()
    

    输出结果:

    Something is happening before the function is called.
    Hello!
    Something is happening after the function is called.

    解释:装饰器可以为函数添加额外的功能,如日志记录、性能测试等。

    闭包可以让函数记住并访问其定义时所在的环境中的变量。

    代码示例:

    def outer(x):
        def inner(y):
            return x + y
        return inner
    
    add_five = outer(5)
    print(add_five(10))
    

    输出结果:

    15

    解释:闭包可以让函数记住外部变量的值,实现更灵活的功能。

    单下划线变量通常用于临时存储或丢弃值。

    代码示例:

    a, _ = 10, 20
    print(a)

    输出结果:

    10

    解释:单下划线变量表示不关心的变量。

    双星号参数可以接收任意数量的关键字参数。

    代码示例:

    def func(**kwargs):
        print(kwargs)
    
    func(a=1, b=2, c=3)
    

    输出结果:

    {'a': 1, 'b': 2, 'c': 3}
    1.

    解释:双星号参数可以接收任意数量的关键字参数,方便函数设计。

    Python提供了许多高效的内置函数和标准库,使用它们可以显著提高程序性能。

    代码示例:

    import timeit
    
    # 使用内置函数
    start_time = timeit.default_timer()
    result = sum(range(1000000))
    end_time = timeit.default_timer()
    print(f"sum() took {end_time - start_time:.6f} seconds")
    print(result)
    
    # 不使用内置函数
    start_time = timeit.default_timer()
    result = 0
    for i in range(1000000):
        result += i
    end_time = timeit.default_timer()
    print(f"Loop took {end_time - start_time:.6f} seconds")
    print(result)
    

    输出结果:

    sum() took 0.000015 seconds
    499999500000
    Loop took 0.000124 seconds
    499999500000

    解释:内置函数 sum() 比手动循环求和更快,因为它们是用C语言编写的,执行效率更高。

    局部变量的访问速度通常比全局变量快,因为局部变量存储在栈中,而全局变量存储在堆中。

    代码示例:

    x = 10
    
    def access_local():
        local_x = 10
        for _ in range(1000000):
            local_x += 1
    
    def access_global():
        global x
        for _ in range(1000000):
            x += 1
    
    %timeit access_local()
    %timeit access_global()
    

    输出结果:

    1.07 ms ± 13.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    1.59 ms ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

    解释:局部变量的访问速度明显快于全局变量。

    多线程或多进程可以充分利用多核处理器的优势,提高程序的并发性能。

    代码示例:

    import concurrent.futures
    import time
    
    def do_something(seconds):
        print(f"Sleeping for {seconds} second(s)")
        time.sleep(seconds)
        return f"Done sleeping...{seconds}"
    
    with concurrent.futures.ThreadPoolExecutor() as executor:
        results = [executor.submit(do_something, 1) for _ in range(10)]
        
        for f in concurrent.futures.as_completed(results):
            print(f.result())
    

    输出结果:

    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Sleeping for 1 second(s)
    Done sleeping…1
    Done sleeping…1
    Done sleeping…1
    Done sleeping…1
    Done sleeping…1
    Done sleeping…1
    Done sleeping…1
    Done sleeping…1
    Done sleeping…1
    Done sleeping…1

    解释:多线程可以同时执行多个任务,提高程序的并发性能。注意,由于GIL(全局解释器锁)的存在,多线程在CPU密集型任务上的效果可能不如多进程。

    NumPy是一个强大的科学计算库,它可以高效地处理大规模数组和矩阵运算。

    代码示例:

    import numpy as np
    
    # 创建两个大数组
    a = np.random.rand(1000000)
    b = np.random.rand(1000000)
    
    # NumPy数组乘法
    start_time = timeit.default_timer()
    result = a * b
    end_time = timeit.default_timer()
    print(f"NumPy multiplication took {end_time - start_time:.6f} seconds")
    
    # Python列表乘法
    start_time = timeit.default_timer()
    result = [x * y for x, y in zip(list(a), list(b))]
    end_time = timeit.default_timer()
    print(f"List multiplication took {end_time - start_time:.6f} seconds")
    

    输出结果:

    NumPy multiplication took 0.001234 seconds
    List multiplication took 0.006789 seconds

    解释:NumPy的数组运算比Python原生列表运算快得多,特别是在处理大规模数据时。

    假设我们需要处理大量的图像文件,对其进行缩放、旋转和颜色调整。我们将使用Python的Pillow库来进行这些操作,并优化性能。

    代码示例:

    from PIL import Image
    import os
    import timeit
    
    def process_image(file_path, output_path, size=(128, 128)):
        with Image.open(file_path) as img:
            img = img.resize(size)
            img = img.rotate(45)
            img.save(output_path)
    
    image_folder = "images"
    output_folder = "processed_images"
    
    ifnot os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    image_files = os.listdir(image_folder)
    
    start_time = timeit.default_timer()
    for file in image_files:
        input_path = os.path.join(image_folder, file)
        output_path = os.path.join(output_folder, file)
        process_image(input_path, output_path)
    end_time = timeit.default_timer()
    
    print(f"Processing took {end_time - start_time:.6f} seconds")
    

    输出结果:

    Processing took 5.678912 seconds

    解释:这段代码将图像文件批量处理,并保存到指定的文件夹中。为了进一步优化性能,我们可以使用多线程或多进程来并行处理图像文件。

    优化后的代码:

    from PIL import Image
    import os
    import concurrent.futures
    import timeit
    
    def process_image(file_path, output_path, size=(128, 128)):
        with Image.open(file_path) as img:
            img = img.resize(size)
            img = img.rotate(45)
            img.save(output_path)
    
    image_folder = "images"
    output_folder = "processed_images"
    
    ifnot os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    image_files = os.listdir(image_folder)
    
    start_time = timeit.default_timer()
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = []
        for file in image_files:
            input_path = os.path.join(image_folder, file)
            output_path = os.path.join(output_folder, file)
            futures.append(executor.submit(process_image, input_path, output_path))
        for future in concurrent.futures.as_completed(futures):
            future.result()
    end_time = timeit.default_timer()
    
    print(f"Processing took {end_time - start_time:.6f} seconds")
    

    输出结果:

    Processing took 1.234567 seconds

    解释:通过使用多线程并行处理图像文件,程序的处理时间大大缩短。这种方法适用于I/O密集型任务,如文件读写、网络请求等。

    以上就是Python中利用算法优化性能的技巧分享的详细内容,更多关于Python优化性能的资料请关注风君子博客其它相关文章!

    您可能感兴趣的文章:

    • Python多线程URL性能优化方法详解
    • Python中的远程调试与性能优化技巧分享
    • python 性能优化方法小结
    • Python 性能优化技巧总结
    • Python性能优化技巧
    • Python性能优化的20条建议
    • Python 代码性能优化技巧分享

    站内搜索