递归函数的精确时间统计
import time
from functools import wraps
# ------------------------------
# 计时装饰器
# ------------------------------
def recursion_timer(func):
"""用于统计递归函数总执行时间的装饰器"""
is_timing = False
start_time = 0.0
@wraps(func)
def wrapper(*args, **kwargs):
nonlocal is_timing, start_time
if not is_timing:
is_timing = True
start_time = time.perf_counter()
result = func(*args, **kwargs)
if is_timing:
is_timing = False
end_time = time.perf_counter()
total_time = end_time - start_time
print(f"递归{func.__name__}({args[0]}) 耗时: {total_time:.8f}秒")
return result
return wrapper
def function_timer(func):
"""用于统计非递归函数执行时间的装饰器"""
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs)
end_time = time.perf_counter()
elapsed_time = end_time - start_time
print(f"非递归{func.__name__}({args[0]}) 耗时: {elapsed_time:.8f}秒")
return result
return wrapper
# ------------------------------
# 阶乘实现
# ------------------------------
@recursion_timer
def factorial_recursive(n):
"""阶乘的递归实现"""
if n <= 1:
return 1
return n * factorial_recursive(n - 1)
@function_timer
def factorial_iterative(n):
"""阶乘的非递归实现"""
result = 1
for i in range(2, n + 1):
result *= i
return result
# ------------------------------
# 斐波那契数列实现
# ------------------------------
@recursion_timer
def fibonacci_recursive(n):
"""斐波那契数列的递归实现"""
if n <= 1:
return n
return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)
@function_timer
def fibonacci_iterative(n):
"""斐波那契数列的非递归实现"""
if n < 0:
raise ValueError("n必须是非负整数")
if n == 0:
return 0
elif n == 1:
return 1
a, b = 0, 1
for _ in range(2, n + 1):
c = a + b
a = b
b = c
return b
# ------------------------------
# 性能对比测试
# ------------------------------
def compare_performance(num):
print(f"\n===== 计算数值: {num} =====")
# 阶乘对比
factorial_recursive(num)
factorial_iterative(num)
# 斐波那契数列对比(注意:递归斐波那契不适合太大的数)
try:
fibonacci_recursive(num)
except RecursionError:
print(f"递归fibonacci({num}) 失败: 递归深度过大")
except Exception as e:
print(f"递归fibonacci({num}) 出错: {str(e)}")
fibonacci_iterative(num)
if __name__ == "__main__":
# 测试较小的数值
compare_performance(10)
compare_performance(20)
# 测试较大的数值(注意:递归斐波那契可能无法完成)
compare_performance(30)
# 只测试非递归实现的大数值性能
print("\n===== 只测试非递归大数值性能 =====")
factorial_iterative(10000)
fibonacci_iterative(10000)
以上代码统计斐波那契数列有问题,递归无问题。修正如下:
import time
from functools import wraps
# 修正的递归计时器
def accurate_recursion_timer(func):
"""精确统计递归函数总耗时的装饰器"""
# 用字典存储状态:是否计时中、开始时间、当前调用计数、总调用次数
state = {'is_timing': False, 'start_time': 0.0, 'call_count': 0, 'total_calls': 0}
@wraps(func)
def wrapper(*args, **kwargs):
# 第一次调用:初始化计时
if not state['is_timing']:
state['is_timing'] = True
state['start_time'] = time.perf_counter()
state['call_count'] = 0
state['total_calls'] = 0 # 记录所有递归调用的总次数
# 每次进入函数,调用计数+1
state['call_count'] += 1
state['total_calls'] += 1
# 执行递归逻辑
result = func(*args, **kwargs)
# 每次离开函数,当前调用计数-1
state['call_count'] -= 1
# 最后一次返回(所有递归调用都已完成)
if state['call_count'] == 0:
end_time = time.perf_counter()
total_time = end_time - state['start_time']
print(f"递归实现(fib({args[0]})) 总耗时: {total_time:.8f} 秒 "
f"(总调用次数: {state['total_calls']})")
# 重置状态,以便下次调用
state['is_timing'] = False
return result
return wrapper
def function_timer(func):
"""非递归函数计时器"""
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
end = time.perf_counter()
print(f"非递归实现(fib({args[0]})) 总耗时: {end - start:.8f} 秒")
return result
return wrapper
# 斐波那契实现
@accurate_recursion_timer
def fibonacci_recursive(n):
if n <= 1:
return n
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
@function_timer
def fibonacci_iterative(n):
if n < 0:
raise ValueError("n必须是非负整数")
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
# 测试
def test():
for n in [10, 20, 30]:
print(f"\n===== 计算第 {n} 项 =====")
fib_rec = fibonacci_recursive(n)
fib_iter = fibonacci_iterative(n)
assert fib_rec == fib_iter, f"结果不一致: 递归={fib_rec}, 非递归={fib_iter}"
if __name__ == "__main__":
test()

浙公网安备 33010602011771号