当前位置: 首页 > news >正文

简述React 和 Vue 的 diff 时间复杂度从 O(n^3) 优化 到 O(n) ,那么 O(n^3) 和 O(n) 是如何计算出来的 ?

React 和 Vue 的 diffing 算法(即虚拟DOM比较算法)的优化过程是一个复杂的过程,涉及到多个层面的设计和优化。从 O(n^3) 优化到 O(n) 的时间复杂度并不是简单地通过一个步骤完成的,而是经过了一系列的改进和优化。

O(n^3) 的可能来源

变成O(n^3)其实是牺牲了最优解,来换取时间

在最初的虚拟DOM diffing算法中,如果采用简单的方法去比较两个树形结构的差异,可能会遇到需要递归比较所有节点的情况。在最坏的情况下,每个节点都需要与其对应的节点以及所有子节点进行比较,这可能导致一个三重循环(对于每个节点,检查其子节点,然后对于每个子节点再检查其子节点),从而可能产生 O(n^3) 的时间复杂度。

优化到 O(n) 的过程

React 和 Vue 都采用了不同的策略来优化 diffing 算法,使其时间复杂度降低到接近 O(n)。以下是一些常见的优化策略:

  1. 基于组件类型的比较

    • 如果两个节点是不同类型的,React 会立即销毁旧的树并构建新的树。
    • Vue 也类似,它会基于虚拟节点的类型来判断是否可以复用节点。
  2. 列表和键(Keys)

    • 对于列表渲染,React 引入了 key 属性来帮助识别哪些项目发生了改变、被添加或被移除。
    • Vue 同样支持使用 :key 绑定来优化列表的渲染。
  3. 使用虚拟DOM的“快照”

    • React 和 Vue 的虚拟DOM不仅仅是一个简单的JS对象树,它们还包含了一些额外的信息来帮助diffing过程。
    • 这些信息可能包括节点的类型、属性、子节点等,并且可以在比较时避免不必要的比较。
  4. 只比较变更的部分

    • React 和 Vue 都采用了某种形式的“变化追踪”或“脏检查”机制,以确定哪些部分需要重新渲染。
    • 这意味着它们不会每次都比较整个树,而只会比较那些已知已经改变或可能改变的部分。
  5. 使用启发式方法

    • React 和 Vue 的diffing算法可能包含一些启发式方法,例如假设列表中的元素很少会改变顺序或位置,从而优化比较过程。

如何计算时间复杂度

时间复杂度的计算通常基于算法的基本操作(如比较、赋值等)的数量,以及这些操作如何随输入数据的大小(n)而变化。

  • O(n^3):如果算法中存在三层嵌套循环,且每一层循环都遍历整个输入数据(或与其大小成比例的某个集合),则时间复杂度可能是 O(n^3)。
  • O(n):如果算法中的基本操作数量与输入数据的大小(n)成线性关系,即无论输入数据多大,基本操作的数量都只是输入数据大小的一个常数倍,则时间复杂度是 O(n)。

需要注意的是,这里的 O(n) 和 O(n^3) 是对算法性能的一种粗略估计,实际表现可能会受到多种因素的影响,包括硬件性能、输入数据的特性、算法的具体实现等。因此,在评估算法性能时,通常需要结合实际情况进行基准测试和性能分析。

相关文章:

  • 特征提取(Feature Extraction)特征评估(五)
  • 【Linux】The server quit without updating PID file的几种解决方案
  • ubuntu20.04设置文件开机自启动
  • 持续总结中!2024年面试必问 20 道分布式、微服务面试题(二)
  • ffmpeg视频编码原理和实战-(2)视频帧的创建和编码packet压缩
  • 6.4分享会
  • 2024全国高考作文题解读(Chat GPT 4.0版本)
  • 讯方618代表有话说 | 行业大咖详解鸿蒙,全程在线答疑
  • java static 如何理解
  • Edge 工作区是什么?它都有哪些作用?
  • 删除目录
  • 【Android Studio】导入import android.support.v7.app.AppcompatActivity;时报错
  • 【机器学习】原理与应用场景 Python代码展现
  • 「前端+鸿蒙」鸿蒙应用开发简介
  • day26-单元测试
  • canvas绘制圆角头像
  • HashMap ConcurrentHashMap
  • JavaScript 基础知识 - 入门篇(一)
  • JavaScript 一些 DOM 的知识点
  • Java基本数据类型之Number
  • Mithril.js 入门介绍
  • mysql 5.6 原生Online DDL解析
  • Next.js之基础概念(二)
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • python学习笔记 - ThreadLocal
  • Rancher-k8s加速安装文档
  • Vue.js-Day01
  • 复习Javascript专题(四):js中的深浅拷贝
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 入口文件开始,分析Vue源码实现
  • 深度学习在携程攻略社区的应用
  • Python 之网络式编程
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 湖北分布式智能数据采集方法有哪些?
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #数据结构 笔记一
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (12)Linux 常见的三种进程状态
  • (javaweb)Http协议
  • (pycharm)安装python库函数Matplotlib步骤
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (二十三)Flask之高频面试点
  • (翻译)terry crowley: 写给程序员
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (九)One-Wire总线-DS18B20
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (转)大型网站的系统架构
  • .NET Core跨平台微服务学习资源
  • .Net 代码性能 - (1)
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .Net小白的大学四年,内含面经
  • .net知识和学习方法系列(二十一)CLR-枚举
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解