返回顶部
分享到

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

python 来源:互联网 作者:佚名 发布时间:2025-04-19 22:31:45 人浏览
摘要

1. 列表推导式(List Comprehension) 列表推导式是一种快速创建列表的方法,它比传统的循环方式更快、更简洁。 代码示例: 1 2 3 4 5 6 7 8 9 10 # 传统方式 squares = [] for i in range(10): squares.append(i **

1. 列表推导式(List Comprehension)

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

代码示例:

1

2

3

4

5

6

7

8

9

10

# 传统方式

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]

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

2. 字典推导式(Dictionary Comprehension)

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

代码示例:

1

2

3

4

5

6

7

8

9

10

# 传统方式

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}

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

3. 集合推导式(Set Comprehension)

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

代码示例:

1

2

3

4

5

6

7

8

9

10

# 传统方式

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}

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

4. 生成器表达式(Generator Expression)

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

代码示例:

1

2

3

4

5

6

7

8

9

10

11

# 传统方式

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
...

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

5. 装饰器(Decorator)

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

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

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.

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

6. 闭包(Closure)

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

代码示例:

1

2

3

4

5

6

7

def outer(x):

    def inner(y):

        return x + y

    return inner

 

add_five = outer(5)

print(add_five(10))

输出结果:

15

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

7. 单下划线变量(_)

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

代码示例:

1

2

a, _ = 10, 20

print(a)

输出结果:

10

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

8. 双星号参数(**kwargs)

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

代码示例:

1

2

3

4

def func(**kwargs):

    print(kwargs)

 

func(a=1, b=2, c=3)

输出结果:

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

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

9. 使用内置函数和标准库

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

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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语言编写的,执行效率更高。

10. 使用局部变量

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

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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)

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

11. 使用多线程或多进程

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

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

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密集型任务上的效果可能不如多进程。

12. 使用NumPy库

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

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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库来进行这些操作,并优化性能。

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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

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

优化后的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

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密集型任务,如文件读写、网络请求等。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计