Python - 递归函数(Recursive Function)的速度优化 (Python实现)

欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://spike.blog.csdn.net/article/details/140137432

免责声明:本文来源于个人知识与开源资料,仅用于学术交流,不包含任何商业技术,欢迎相互学习,不支持转载。


Recursive

递归函数 是特殊的编程技术,通过调用自身来解决问题。递归函数通常包含两个关键部分:基线条件(Base Case)递归步骤(Recursive Step),包括:

  • 递归函数(Recursive Function):递归函数是调用自身的函数。允许程序,通过将问题分解为更小的、更易于管理的子问题,来解决问题。递归函数通常用于解决可以自然分解为相似子问题的问题,如树的遍历、排序算法(如快速排序和归并排序)等。
  • 基线条件(Base Case):基线条件是递归函数中,用来停止递归调用的条件。没有基线条件,递归将无限进行下去,最终导致栈溢出错误。基线条件通常是一个或多个特定情况,当满足这些条件时,递归函数将返回一个不需要进一步递归调用的值。
  • 结果缓存(Memoization):结果缓存是一种优化技术,用于存储递归函数的计算结果,以避免重复计算相同的子问题。这在具有大量重复计算的递归算法中非常有用。通过缓存结果,显著提高递归函数的性能,在 Python 中,使用字典结构 dict() 作为缓存。
  • LRU 缓存装饰器(LRU Cache Decorator):LRU,即 Least Recently Used,是常用于缓存最近最少使用的数据的数据结构。LRU缓存装饰器可以应用于递归函数,以实现自动的结果缓存和过期策略。这有助于管理内存使用,提高具有大量重复调用的递归函数的性能。
  • 生成器(Generator):生成器是一种特殊的迭代器,允许惰性地生成值,即一次生成一个值,而不是一次性生成所有值。在 Python 中,生成器使用 yield 关键字实现。生成器对于处理大型数据集或实现复杂的迭代逻辑非常有用,并且可以与递归结合使用,以简化代码并提高效率。

运行效率排序:迭代 > LRU 缓存 > 字典缓存 > 普通递归

即:

#!/usr/bin/env python
# -- coding: utf-8 --
"""
Copyright (c) 2024. All rights reserved.
Created by C. L. Wang on 2024/7/2
"""

import time


def fib2(n):
    """
    递归实现斐波那契数列
    """
    if n <= 1:  # 基线条件
        return n
    return fib2(n - 2) + fib2(n - 1)


memo = {0: 0, 1: 1}


def fib3(n):
    """
    递归实现斐波那契数列,使用字典缓存
    """
    if n in memo:
        return memo[n]
    memo[n] = fib3(n - 2) + fib3(n - 1)
    return memo[n]


from functools import lru_cache


@lru_cache(maxsize=None)
def fib4(n):
    """
    递归实现斐波那契数列,使用lru_cache缓存
    """
    if n <= 1:  # 基线条件
        return n
    return fib4(n - 2) + fib4(n - 1)


def fib5(n):
    """
    迭代实现斐波那契数列
    """
    if n == 0:
        return 0
    last, _next = 0, 1
    for _ in range(1, n):
        last, _next = _next, last + _next
    return _next


def fib6(n):
    """
    生成器输出斐波那契数列
    """
    yield 0
    if n > 0:
        yield 1
    last, _next = 0, 1
    for _ in range(1, n):
        last, _next = _next, last + _next
        yield _next


if __name__ == '__main__':
    s_time = time.time()
    print(f"fib2: {fib2(30)}, time: {(time.time() - s_time)*1000:.4f} ms")
    s_time = time.time()
    print(f"fib3: {fib3(30)}, time: {(time.time() - s_time)*1000:.4f} ms")
    s_time = time.time()
    print(f"fib4: {fib4(30)}, time: {(time.time() - s_time)*1000:.4f} ms")
    s_time = time.time()
    print(f"fib5: {fib5(30)}, time: {(time.time() - s_time)*1000:.4f} ms")
    for i in fib6(10):
        print(i, end=' ')

运行输出:

fib2: 832040, time: 213.8369 ms
fib3: 832040, time: 0.0222 ms
fib4: 832040, time: 0.0148 ms
fib5: 832040, time: 0.0043 ms
0 1 1 2 3 5 8 13 21 34 55 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/765695.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RTSP协议在视频监控系统中的典型应用、以及视频监控设备的rtsp地址格式介绍

目录 一、协议概述 1、定义 2、提交者 3、位置 二、主要特点 1、实时性 2、可扩展性 3、控制功能 4、回放支持 5、网络适应性 三、RTSP的工作原理 1、会话准备 2、会话建立 3、媒体流控制 4、会话终止 5、媒体数据传输 四、协议功能 1、双向性 2、带外协议 …

Studying-代码随想录训练营day26| 491.递增子序列、46.全排列、47.全排列 II、51.N皇后、37.解数独、回溯总结

第26天&#xff0c;回溯part04&#xff0c;昨天休息复习总结回溯内容&#xff0c;&#x1f4aa;(ง •_•)ง&#x1f4aa; 目录 491.递增子序列 46.全排列 47.全排列 II 51.N皇后 37.解数独 回溯总结 491.递增子序列 文档讲解&#xff1a;代码随想录递增子序列 视频讲…

d3dcompiler47dll丢失怎么解决,总结几种靠谱的方法

在日常生活和工作中&#xff0c;电脑已经成为我们不可或缺的工具。然而&#xff0c;在使用电脑的过程中&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中之一就是“找不到d3dcompiler_47.dll”。这个问题可能会对电脑系统的正常运行造成一定的影响&#xff0c;因此我们…

多商户b2b2c商城系统怎么运营

B2B2C多用户商城系统支持多种运营模式&#xff0c;以满足不同类型和发展阶段的企业需求。以下是五大主要的运营模式&#xff1a; **1. 自营模式&#xff1a;**平台企业通过建立自营线上商城&#xff0c;整合自身多渠道业务。通过会员、商品、订单、财务和仓储等多用户商城管理系…

旧版st7789屏幕模块 没有CS引脚的天坑 已解决!!!

今天解决了天坑一个&#xff0c;大家可能有的人买的是st7789屏幕模块&#xff0c;240x240&#xff0c;1.3寸的 他标注的是老版&#xff0c;没有CS引脚&#xff0c;小崽子长这样&#xff1a; 这熊孩子用很多通用的驱动不吃&#xff0c;死活不显示&#xff0c;网上猛搜&#xff…

【简单讲解神经网络训练中batch的作用】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

pdf怎么拆分成一页一页?4种拆分方法分享

在日常的办公学习中&#xff0c;PDF文档因其跨平台、易阅读、不易篡改等特性&#xff0c;成为我们工作和学习中不可或缺的一部分。然而&#xff0c;当我们需要对PDF进行编辑、打印或分享时&#xff0c;有时需要将整个PDF文档拆分成一页一页的单独文件。那么&#xff0c;如何高效…

嵌入式学习——硬件(Linux系统在2440上的启动)——day57

1. Linux2.6系统在s3c2440上的启动过程分三个阶段 1.1 启动u-boot 1.2 启动Linux内核 1.3 挂载根文件系统 2. bootloader 2.1 定义 bootloader的本质是一个裸机程序&#xff0c;bootlood专门是为了能够正确地启动linux操作系 统&#xff0c;在系统初上电时需要对系统做一些…

TFD那智机器人仿真离线程序文本转换为现场机器人程序

TFD式样那智机器人离线程序通过Process Simulation、DELMIA等仿真软件为载体给机器人出离线&#xff0c;下载下来的文本程序&#xff0c;现场机器人一般是无法导入及识别出来的。那么就需要TFD on Desk TFD控制器来进行转换&#xff0c;才能导入现场机器人读取程序。 导入的文…

CAN通信波形【示波器抓取】

在测试bms系统过程中&#xff0c;在上位机发现无法读取CAN通信&#xff0c;尝试使用示波器抓取CAN通信波形&#xff0c;&#xff0c;去确定CAN通信是否正常。 做一想要从车上测出can总线上的数据还不太容易。 于是我首先使用示波器&#xff08;我使用的示波器型号是TDS 220&am…

NSSCTF-Web题目19(数据库注入、文件上传、php非法传参)

目录 [LitCTF 2023]这是什么&#xff1f;SQL &#xff01;注一下 &#xff01; 1、题目 2、知识点 3、思路 [SWPUCTF 2023 秋季新生赛]Pingpingping 4、题目 5、知识点 6、思路 [LitCTF 2023]这是什么&#xff1f;SQL &#xff01;注一下 &#xff01; 1、题目 2、知识…

全球首款商用,AI为视频自动配音配乐产品上线

近日&#xff0c;海外推出了一款名为Resona V2A的产品&#xff0c;这是全球首款商用视频转音频 (V2A) 技术产品。这项突破性技术利用AI&#xff0c;仅凭视频数据即可自动生成高质量、与上下文相关的音频&#xff0c;包括声音设计、音效、拟音和环境音&#xff0c;为电影制作人、…

【LeetCode】十、二分查找法:寻找峰值 + 二维矩阵的搜索

文章目录 1、二分查找法 Binary Search2、leetcode704&#xff1a;二分查找3、leetcode35&#xff1a;搜索插入位置4、leetcode162&#xff1a;寻找峰值5、leetcode74&#xff1a;搜索二维矩阵 1、二分查找法 Binary Search 找一个数&#xff0c;有序的情况下&#xff0c;直接…

从零开始实现大语言模型(二):文本数据处理

1. 前言 神经网络不能直接处理自然语言文本&#xff0c;文本数据处理的核心是做tokenization&#xff0c;将自然语言文本分割成一系列tokens。 本文介绍tokenization的基本原理&#xff0c;OpenAI的GPT系列大语言模型使用的tokenization方法——字节对编码(BPE, byte pair en…

Apache POI、EasyPoi、EasyExcel

目录 ​编辑 &#xff08;一&#xff09;Apache PoI 使用 &#xff08;二&#xff09;EasyPoi使用 &#xff08;三&#xff09;EasyExcel使用 写 读 最简单的读​ 最简单的读的excel示例​ 最简单的读的对象​ &#xff08;一&#xff09;Apache PoI 使用 &#xff08;二&…

33 包装器

c11 也叫适配器。c中的function本质是一个类模板&#xff0c;也是一个包装器 为什么需要fuction呢&#xff1f; 当一个类型既可以是函数指针&#xff0c;也可以是仿函数和lambda比倒是&#xff0c;函数指针的类型不好理解&#xff0c;仿函数写起来麻烦&#xff0c;lambda无法拿…

2024年工程项目管理者的软件指南:11款必试进度管理工具

本文将分享11个值得关注的工程项目进度管理软件&#xff1a;Worktile、Fieldwire、Procore、Buildxact、InEight、Contractor Foreman、Housecall Pro、ClickUp、RedTeam Go、Visual Planning、B2W Schedule。 在竞争激烈的建筑行业&#xff0c;工程项目的进度管理是项目成功的…

Linux 实现自定义系统调用,支持参数和结果返回

本文实现一个简单的系统调用实现&#xff0c;支持输入字符串参数&#xff0c;并返回一个结果字符串。 以下是验证步骤&#xff1a; 1. 添加系统调用编号 试验使用的是 x86_64 架构的 Linux 内核。 找到并编辑 arch/x86/entry/syscalls/syscall_64.tbl 文件&#xff0c;在文件…

编写动态库

1.创建库.c .h文件 2.编写Makefile文件 3.make之后形成.so文件 4.make output,形成mylib 5.把mylib拷贝到test里面 mv mylib /test 6.编译 gcc main.c -I mylib/include -L mylib/lib -lmymethod形成a.out 但是直接执行会出现以下问题 很显然没有找到动态库 7.解决加载找不…

主干网络篇 | YOLOv8改进之引入YOLOv10的主干网络 | 全网最新改进

前言:Hello大家好,我是小哥谈。YOLOv10是由清华大学研究人员利用Ultralytics Python软件包开发的,它通过改进模型架构并消除非极大值抑制(NMS)提供了一种新颖的实时目标检测方法。这些优化使得模型在保持先进性能的同时,降低了计算需求。与以往的YOLO版本不同,YOLOv10的…