python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python性能优化

Python性能优化之让你的代码运行速度提升10倍的技巧分享

作者:天天进步2015

在日常开发中,我们常常会遇到Python代码运行缓慢的问题,通过一些巧妙的优化技巧,我们完全可以让代码的运行速度提升数倍甚至数十倍,下面小编就为大家介绍一下吧

在日常开发中,我们常常会遇到Python代码运行缓慢的问题。虽然Python以其简洁优雅著称,但性能往往不是它的强项。不过,通过一些巧妙的优化技巧,我们完全可以让代码的运行速度提升数倍甚至数十倍。今天,我将分享一些实战中验证过的性能优化方法。

1. 选择正确的数据结构

数据结构的选择对性能影响巨大。使用合适的数据结构,往往能带来指数级的性能提升。

使用set进行查找操作

当需要频繁判断元素是否存在时,set的查找时间复杂度是O(1),而list是O(n)。

# 慢速版本
def find_in_list(items, targets):
    result = []
    for target in targets:
        if target in items:  # O(n) 查找
            result.append(target)
    return result

# 快速版本
def find_in_set(items, targets):
    items_set = set(items)  # 一次性转换
    result = []
    for target in targets:
        if target in items_set:  # O(1) 查找
            result.append(target)
    return result

使用dict代替多个if-elif

# 慢速版本
def get_discount(level):
    if level == 'bronze':
        return 0.05
    elif level == 'silver':
        return 0.10
    elif level == 'gold':
        return 0.15
    elif level == 'platinum':
        return 0.20
    else:
        return 0

# 快速版本
def get_discount(level):
    discounts = {
        'bronze': 0.05,
        'silver': 0.10,
        'gold': 0.15,
        'platinum': 0.20
    }
    return discounts.get(level, 0)

2. 利用内置函数和标准库

Python的内置函数用C语言实现,速度远快于纯Python代码。

使用map和filter

# 慢速版本
numbers = range(1000000)
result = []
for num in numbers:
    result.append(num * 2)

# 快速版本
numbers = range(1000000)
result = list(map(lambda x: x * 2, numbers))

# 更快:列表推导式
result = [num * 2 for num in numbers]

利用collections模块

from collections import Counter, defaultdict, deque

# 统计元素出现次数
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
# 快速统计
count = Counter(words)

# 使用defaultdict避免键检查
word_positions = defaultdict(list)
for i, word in enumerate(words):
    word_positions[word].append(i)

# 使用deque实现高效的队列操作
queue = deque()
queue.append(1)  # O(1)
queue.popleft()  # O(1),list.pop(0)是O(n)

3. 避免不必要的计算

缓存重复计算结果

from functools import lru_cache

# 慢速版本:重复计算
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# 快速版本:使用缓存
@lru_cache(maxsize=None)
def fibonacci_cached(n):
    if n < 2:
        return n
    return fibonacci_cached(n-1) + fibonacci_cached(n-2)

# fibonacci(35) 可能需要几秒
# fibonacci_cached(35) 几乎瞬间完成

延迟计算和生成器

# 慢速版本:一次性创建所有数据
def process_large_file(filename):
    with open(filename) as f:
        lines = f.readlines()  # 一次性读入内存
        return [line.strip().upper() for line in lines]

# 快速版本:使用生成器
def process_large_file_lazy(filename):
    with open(filename) as f:
        for line in f:  # 逐行处理
            yield line.strip().upper()

# 使用
for processed_line in process_large_file_lazy('huge_file.txt'):
    # 处理每一行,内存占用小
    pass

4. 字符串操作优化

字符串拼接是常见的性能瓶颈。

# 慢速版本:使用+拼接
def join_strings_slow(strings):
    result = ""
    for s in strings:
        result += s  # 每次创建新字符串对象
    return result

# 快速版本:使用join
def join_strings_fast(strings):
    return "".join(strings)

# 性能对比:处理10000个字符串
# 慢速版本:约0.5秒
# 快速版本:约0.001秒(快500倍)

5. 循环优化技巧

减少点号查找

import math

# 慢速版本
def calculate_slow(numbers):
    result = []
    for num in numbers:
        result.append(math.sqrt(num))  # 每次都要查找math.sqrt
    return result

# 快速版本
def calculate_fast(numbers):
    sqrt = math.sqrt  # 局部变量查找更快
    result = []
    for num in numbers:
        result.append(sqrt(num))
    return result

# 更快:列表推导式
def calculate_fastest(numbers):
    sqrt = math.sqrt
    return [sqrt(num) for num in numbers]

使用enumerate代替range(len())

items = ['a', 'b', 'c', 'd']

# 慢速版本
for i in range(len(items)):
    print(i, items[i])

# 快速版本
for i, item in enumerate(items):
    print(i, item)

6. 并行处理和多线程

对于CPU密集型任务,使用多进程;对于IO密集型任务,使用多线程或异步IO。

from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import time

# CPU密集型任务示例
def cpu_bound_task(n):
    return sum(i * i for i in range(n))

# 使用多进程
def process_with_multiprocessing(numbers):
    with ProcessPoolExecutor() as executor:
        results = list(executor.map(cpu_bound_task, numbers))
    return results

# IO密集型任务使用多线程
import requests

def download_url(url):
    response = requests.get(url)
    return len(response.content)

def download_parallel(urls):
    with ThreadPoolExecutor(max_workers=10) as executor:
        results = list(executor.map(download_url, urls))
    return results

7. 使用NumPy进行数值计算

对于数值计算,NumPy比纯Python快几十倍甚至上百倍。

import numpy as np

# 慢速版本:纯Python
def sum_of_squares_python(n):
    return sum(i**2 for i in range(n))

# 快速版本:NumPy
def sum_of_squares_numpy(n):
    arr = np.arange(n)
    return np.sum(arr**2)

# 性能对比(n=1000000)
# Python版本:约0.5秒
# NumPy版本:约0.01秒(快50倍)

8. 性能分析工具

找出性能瓶颈比盲目优化更重要。

import cProfile
import pstats

# 使用cProfile分析
def my_function():
    # 你的代码
    pass

profiler = cProfile.Profile()
profiler.enable()
my_function()
profiler.disable()

stats = pstats.Stats(profiler)
stats.sort_stats('cumulative')
stats.print_stats(10)  # 显示最慢的10个函数

# 使用line_profiler进行行级分析
# pip install line_profiler
# 在函数前添加@profile装饰器
# 运行:kernprof -l -v script.py

9. 避免全局变量

局部变量的访问速度比全局变量快。

GLOBAL_LIST = list(range(10000))

# 慢速版本
def process_global():
    result = 0
    for item in GLOBAL_LIST:
        result += item
    return result

# 快速版本
def process_local():
    local_list = GLOBAL_LIST  # 创建局部引用
    result = 0
    for item in local_list:
        result += item
    return result

10. 使用__slots__优化类

对于需要创建大量实例的类,使用__slots__可以显著减少内存占用并提升速度。

# 普通类
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

# 优化类
class PointOptimized:
    __slots__ = ['x', 'y']
    
    def __init__(self, x, y):
        self.x = x
        self.y = y

# 创建100万个实例
# 普通类:约300MB内存
# 优化类:约150MB内存(节省50%)

总结

Python性能优化是一门艺术,需要在代码可读性和执行效率之间找到平衡。记住以下几个原则:

记住,过早优化是万恶之源。首先写出清晰正确的代码,然后用数据驱动优化决策。通过合理运用这些技巧,你的Python代码性能提升10倍完全不是梦想!

到此这篇关于Python性能优化之让你的代码运行速度提升10倍的技巧分享的文章就介绍到这了,更多相关Python性能优化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文