HarmonyOS开发实战( Beta5版)应用性能工具CPU Profiler的使用规范

news2024/11/26 3:49:40

简介

本文档介绍应用性能分析工具CPU Profiler的使用方法,该工具为开发者提供性能采样分析手段,可在不插桩情况下获取调用栈上各层函数的执行时间,并展示在时间轴上。

开发者可通过该工具查看TS/JS代码及NAPI代码执行过程中的时序及耗时情况,进而发现热点函数及性能瓶颈,进行应用层性能优化。

性能数据分析视图说明

性能数据可以通过DevEco Studio > Profiler > Time > ArkTS CallstackChrome浏览器 > JavaScript Profiler进行展示和分析。前者提供Callstack泳道图、Details图;后者提供时序火焰图(Chart)、比重图(Heavy)、树形图(Tree)。

DevEco Studio Profiler视图

说明:

该工具自DevEco Studio 4.0 beta2之后开始提供。请各位开发者将DevEco Studio更新至最新版本,以使用该工具。

ArkTS Callstack泳道图

泳道图展示了时间轴上每个时刻正在执行的函数或者正处于的阶段,对于函数来讲可理解为每个时刻调用栈的栈顶。可以通过 Ctrl+鼠标滚轮 任意放大和缩小鼠标所在位置的某一段。

NAPI方法在泳道图上被特殊标记为黄色,此类方法会调用到Native代码,在Details图中可查看到该类方法的Native调用栈。

图1 ArkTS Callstack泳道图

ArkTS Callstack泳道图

Details图

在泳道图上点击任意时间条,或者选定一个起始和终止范围,工具将在下方Details图中显示此时间条代表的函数或者此范围内所有函数的完整调用链,右侧Heaviest Stack视图展示该范围内耗时最长的调用链。

图2 阶段耗时详情示意图

阶段耗时详情示意图

从上图中我们不仅可以看到JS调用栈,还可以看到NAPI接口Native实现部分的C++调用栈。

对于JS方法及开发者自定义的Native方法,双击Details中该方法所在行可跳转到代码行。

说明:

当前行号尚未完全对齐函数头行号,实际为函数内部可执行代码的第一行。

Chrome浏览器JavaScript Profiler工具视图

Chrome浏览器JavaScript Profiler工具默认调用V8引擎提供的Profiler工具,可抓取网页JS性能数据。本文提供的TS/JS CPU Profiler工具的性能数据(.cpuprofile)格式与其兼容,可直接导入到该工具进行分析。

在 Chrome 浏览器上打开JavaScript Profiler工具并加载数据文件的操作步骤为:F12 > More tools > JavaScript Profiler > Load

操作步骤示意图如下所示:

图3 JavaScript Profiler工具入口

JavaScript Profiler工具入口

图4 加载cpuprofile文件

加载cpuprofile文件

如果找不到此工具,可勾选下图选项后F12重新打开。

图5 启用JavaScript Profiler功能

启用JavaScript Profiler功能

该工具可将性能分析数据展示在三种视图:时序火焰图(Chart)、比重图(Heavy)、树形图(Tree)。

时序火焰图(Chart)

图6 时序火焰图(Chart)总览

时序火焰图(Chart)总览

该视图从时间维度展示应用运行过程中每个时刻的函数调用栈,最为直观,时间轴0时刻代表开始采集,可通过鼠标滚轮放大局部。

图7 时序火焰图(Chart)详情

时序火焰图(Chart)详情

可将鼠标放在某一函数上,展示该函数详细信息,详情中包含以下几个字段:

  • Name:格式为“函数名(标签)”。函数名表示TS/JS代码函数名,标签信息代表函数类型

  • Self Time:以毫秒(ms)为单位。表示该函数本次调用过程中,除去调用下一级函数所消耗时间后的自身执行耗时。计算方法为该函数本次调用的总耗时减去该函数本次调用下一级所有函数的总时间。

  • Total Time:以毫秒(ms)为单位。表示该函数本次调用过程中的总耗时,包含调用下一级函数所消耗的时间。

  • URL:格式为“文件路径:行号”。表示该函数在TS/JS代码中的具体位置,包含所在文件及在该文件中的具体行号,该行号为函数头所在行号。

    说明:

    • 当前还存在部分函数URL并未进行sourcemap转换的情况,这部分函数的URL在build目录下。

    • 当前行号尚未完全对齐函数头行号,实际为函数内部可执行代码的第一行。

  • Aggregated self time:以毫秒(ms)为单位。表示该函数在整个采样过程中历次调用的Self Time的总和(仅限上级调用栈一致的多次调用求和)。

  • Aggregated total time:以毫秒(ms)为单位。表示该函数在整个采样过程中历次调用的Total Time的总和(仅限上级调用栈一致的多次调用求和)。

比重图(Heavy)

比重图列出了所有调用栈的栈顶,可以理解为时序火焰图从下往上看,看到的首先是调用链末端函数,以及各自的Self Time时间,将比重图的所有Self Time的比例相加结果为100%。

具体到某一个函数,点击箭头展开,可以看到调用该函数的完整调用链,可能包含多条调用链,指代这些调用链最终都会调用到该函数。

该图表可按照Self Time的大小排序,排在最前面的代表对应函数的Self Time耗时最长,可以作为重点进行分析。

如下两图分别为Chrome浏览器比重图(Heavy)和VSCode比重图(Heavy)对同一.cpuprofile文件的解析结果。不难发现,两种解析方式的时间有所差异,该差异是由计算方式的不同导致的。

Chrome浏览器比重图(Heavy)的时间并不是实际时间,而是通过函数的命中率乘以总时间得到;而VSCode比重图(Heavy)的时间是实际耗时。

做精确分析时建议使用VSCode进行解析,直接用VSCode打开.cpuprofile文件即可。

图8 Chrome比重图(Heavy)示例

Chrome比重图(Heavy)示例

图9 VSCode比重图(Heavy)示例

VSCode比重图(Heavy)示例

树形图(Tree)

树形图列出了所有调用栈的栈底,可以理解为时序火焰图从上往下看,看到的首先是调用链的起始函数,以及各自的Total Time时间,将树形图的所有Total Time的比例相加结果为100%。

具体到某一个函数,箭头展开,可以看到该函数调用的完整调用链,可能包含多条调用链,指代这些调用链都是从该函数调用下去的。

该图表可按照Total Time的大小排序,排在最前面的代表对应函数的Total Time耗时最长,可以作为重点进行分析。

图10 树形图(Tree)示例

树形图(Tree)示例

函数名标签(TAG)的相关说明

各类视图中函数名可能包含(TAG)格式标签,例如func1(AOT),或者函数名仅为(TAG)格式,例如(program)。

函数名包含(TAG)标签

当前支持8类函数名标签,分别是(NAPI)、(ARKUI_ENGINE)、(BUILTIN)、(GC)、(AINT)、(CINT)、(AOT)、(RUNTIME)。可为应用开发者及系统开发者对各部分进行性能分析提供参考。后四种标签通过非命令方式采集时默认不可见,可通过命令 hdc shell param set persist.ark.properties 0x505c; hdc shell reboot 打开。

  • (NAPI) :系统NativeAPI或者开发者在DevEco Studio上自定义的NativeAPI,例如模板Native C++应用中的 testNapi.add()

  • (ARKUI_ENGINE):Native实现的ArkUI组件,例如:onClick(),此类函数暂无法提供函数名。

  • (BUILTIN):由虚拟机提供的、Native实现的JS标准库接口,例如:JSON.stringify()

  • (GC):垃圾回收阶段。

  • (AINT):TS/JS方法,该方法通过虚拟机的汇编解释器解释执行。

  • (CINT):TS/JS方法,该方法通过虚拟机的C解释器解释执行。

  • (AOT):TS/JS方法,该方法通过虚拟机的AOT(Ahead Of Time)编译器提前编译成了机器码,在满足编程规范的前提下可以获得充分编译加速,执行时间比解释执行快。

  • (RUNTIME):Native接口(NAPI, ARKUI_ENGINE, BUILTIN)调用该方法时,表示该方法调用到了虚拟机内部运行时代码。

函数名仅为(TAG)标签

该类标签代表的是一类特殊节点,并非实际函数,包含三种,分别是(root)、(program)、(idle),具体含义如下。

  • (root):根节点,是program和idle以及所有栈底的父节点,可以理解为main函数的上一层。

  • (program):代表程序执行进入纯Native代码阶段,该阶段无JS代码执行,也无JS调用Native或者Native调用JS情况,可能处于系统框架层代码执行阶段。

  • (idle):被采集线程无任务执行或处于非running态,未占用CPU。

    说明:

    当前尚未统计(idle)阶段,该部分时间包含在(program)阶段中。

(TAG)标签时间占比统计

cpuprofile文件以json格式打开,json开头有各个TAG的总时间字段,单位为微秒(us),其中otherTime字段代表(idle)、(root)、(program)三种TAG的总时间。可以据此计算出每种TAG标签的耗时占比,为性能分析提供参考。

图11 时间占比统计示例

时间占比统计示例

数据采集方法及适用场景

各采集工具适用场景及支持情况

采集方法DevEco Studio ProfilerJavaScript Profilerhdc shell应用代码插桩
debug应用支持支持支持支持
release应用暂不支持暂不支持支持支持
采集主线程支持支持支持支持
采集Worker线程暂不支持支持支持支持
采集启动后数据支持支持支持支持
采集冷启动数据暂不支持不支持支持支持

DevEco Studio Profiler工具采集

  1. 启动应用,打开DevEco Studio并确保连接到设备(右上角显示设备SN)。

  2. 按照下图所示①-⑤的步骤打开 Profiler > Time ,选择设备及应用,创建一个新的Time Session监视器。

    图12 DevEco Studio Profiler采集指引

    DevEco Studio Profiler采集指引

  3. 点击开始录制按钮,箭头变成方块代表开始录制。

  4. 操作应用,复现待分析场景。

  5. 再次点击录制按钮,方框变成灰色,结束录制。

  6. 选择ArkTS Callstack泳道,框选时间范围或者直接选择函数进行分析

Chrome浏览器JavaScript Profiler工具采集

  1. 启动应用,可通过如下命令查看应用线程号。如果要抓Worker线程,列表中会有长线程号(长度是短线程号的两倍),每个Worker线程对应一个长线程号。

    hdc shell "netstat -anp | grep PandaDebugger"
  2. 绑定线程号和端口。多个Worker线程同时采集需各自绑定不同的端口号,打开多个Chrome窗口采集。

    说明:

    • 建议选择较大端口号避免冲突,这里以9006为例。

    • 每次断开连接或退出进程后需重新绑定端口号。

    • 多个Worker线程同时采集需各自绑定不同的端口号,打开多个Chrome窗口采集。

    hdc shell "netstat -anp | grep PandaDebugger"

    图13 端口映射

    端口映射

  3. 在Chrome浏览器输入网址: devtools://devtools/bundled/inspector.html?ws=//127.0.0.1:9006 ,端口号与上文一致,点击回车,进入JavaScript Profiler页面。

  4. 点击左上角录制按钮,按钮变为红色开始录制。

  5. 操作应用,复现待分析场景。

  6. 再次点击录制按钮,按钮变为灰色结束录制。

  7. 点击左上角性能分析报告,右侧显示性能分析图表,可以选择图表类型,显示数据表或者火焰图,具体可见 Chrome浏览器JavaScript Profiler工具视图。

    图14 JavaScript Profile视图布局

    JavaScript Profile视图布局

hdc shell命令采集

  1. 根据场景设置对应虚拟机参数。

    • 采集冷启动数据

      # 仅采集主线程冷启动
      hdc shell param set persist.ark.properties 0x705c
      # 仅采集Worker线程冷启动
      hdc shell param set persist.ark.properties 0x1505c
      # 同时采集主线程及Worker线程冷启动 
      hdc shell param set persist.ark.properties 0x1705c
    • 采集启动后任意阶段

      # 仅采集主线程任意阶段
      hdc shell param set persist.ark.properties 0x2505c 
      # 仅采集Worker线程任意阶段
      hdc shell param set persist.ark.properties 0x4505c
      # 同时采集主线程及Worker线程任意阶段 
      hdc shell param set persist.ark.properties 0x6505c
  2. 针对冷启动数据的采集,需设置待采集应用的包名。此处以 com.ohos.example 为例。

    hdc shell param set persist.ark.arkbundlename com.ohos.example
  3. 重启设备。

    hdc shell reboot
  4. 启动应用,会在拉起应用前自动开始采集数据。

  5. 操作应用,复现待分析场景。

  6. 针对启动后任意阶段数据的采集,需使用如下命令,开始采集,其中 pid 为应用进程号。

    hdc shell kill -39 pid
  7. 操作应用,复现待分析场景。

  8. 停止采集数据,其中 pid 为应用进程号。

    hdc shell kill -39 pid
  9. 拉取cpuprofile文件。此处以com.ohos.example为例,文件实际位置及文件名以实际应用为准。

    说明:

    步骤6~8可重复执行多次,会分别采集多个阶段,生成多个.cpuprofile文件。

    每次采集的次数后缀会加1,初始次数为1。冷启动数据无次数后缀。

    # 主线程:
    # 通常非系统应用抓取后cpuprofile通常存储在/data/app/el2/100/base/<bundle_name>/files/
    hdc file recv /data/app/el2/100/base/com.ohos.example/files/com.ohos.example_次数.cpuprofile ./
    # 系统应用存储在/data/app/el2/0/base/<bundle_name>/files/
    hdc file recv /data/app/el2/0/base/com.ohos.example/files/com.ohos.example_次数.cpuprofile ./
    # Worker线程:
    # 通常非系统应用cpuprofile通常存储在/data/app/el2/100/base/<bundle_name>/files/
    hdc file recv /data/app/el2/100/base/com.ohos.example/files/com.ohos.example_线程id_次数.cpuprofile ./
    # 系统应用存储在/data/app/el2/0/base/<bundle_name>/files/
    hdc file recv /data/app/el2/0/base/com.ohos.example/files/com.ohos.example_线程id_次数.cpuprofile ./
  10. 将 com.ohos.example.cpuprofile 文件导入Chrome浏览器 > JavaScript Profiler进行分析,具体可见 Chrome浏览器JavaScript Profiler工具视图。

    图15 加载cpuprofile文件

    加载cpuprofile文件

应用代码插桩采集

  1. 在应用代码中按照如下方式插桩,并打包、安装应用。

    说明:

    插桩位置建议选择为不会重复执行的关键位置,例如onClick中的首行和末行;若重复执行start、stop,仅有第一次的start、stop会成功执行。

    import hidebug from '@ohos.hidebug';
    // 参数为输出文件的文件名,无需加后缀。该参数为必要参数。
    hidebug.startJsCpuProfiling("filename");
    // code block
    // ...
    // code block
    hidebug.stopJsCpuProfiling("filename");
  2. 启动并操作应用,复现待分析场景,确保插桩代码行能执行到。

  3. 拉取json文件并将后缀更改为cpuprofile。此处以com.ohos.example为例,文件实际位置及文件名以实际应用为准。

    # 通常非系统应用抓取后cpuprofile通常存储在/data/app/el2/100/base/<bundle_name>/files/
    hdc file recv /data/app/el2/100/base/com.ohos.example/files/filename.json ./filename.cpuprofile
    
    # 系统应用存储在/data/app/el2/0/base/<bundle_name>/files/
    hdc file recv /data/app/el2/0/base/com.ohos.example/files/filename.json ./filename.cpuprofile
  4. 将 filename.cpuprofile 文件导入Chrome浏览器 > JavaScript Profiler进行分析,具体可见 Chrome浏览器javascript-profiler工具视图。

    图16 加载cpuprofile文件

    加载cpuprofile文件

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为资料太多,太杂,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。 

为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:


 鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频学习教程+学习PDF文档

HarmonyOS Next 最新全套视频教程

  纯血版鸿蒙全套学习文档(面试、文档、全套视频等)       

​​

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web-gpt

AJAX AJAX&#xff08;Asynchronous JavaScript and XML&#xff0c;异步JavaScript和XML&#xff09;是一种用于创建动态网页应用的技术。它允许网页在不重新加载整个页面的情况下&#xff0c;异步地从服务器请求数据&#xff0c;并将这些数据更新到网页上。这提高了用户体验…

HarmonyOS开发实战( Beta5版)小程序场景性能优化开发指导

简介 小程序是一种轻量级的应用&#xff0c;它不需要下载、安装即可使用&#xff0c;用户可以通过扫描二维码或者搜索直接打开使用。小程序运行在特定的平台上&#xff0c;平台提供了小程序的运行环境&#xff08;运行容器&#xff09;和一些基础服务&#xff08;小程序API&am…

【C++ 第十八章】C++11 新增语法(2)

前情回顾&#xff1a; 【C11 新增语法&#xff08;1&#xff09;&#xff1a;1~6 点】 C11出现与历史、花括号统一初始化、initializer_list初始化列表、 auto、decltype、nullptr、STL的一些新变化 本文会使用到自己模拟实现的 string 和 list 类&#xff0c;为了更好的观察各…

笔记整理—内核!启动!—uboot部分(2)

上文中&#xff0c;我们说到了使用uboot去启动kernel支持的几种方式以及压缩kernel的几种形式&#xff0c;本章节将要接着内核的启动说起。 上一章我们对uImage格式进行了初步的说明&#xff0c;并说这样的格式已经被废弃&#xff0c;但是依然保留了相应的代码。boot_get_kerne…

MATLAB生成mif文件

MATLAB代码 % 参数设置 N 4096; % 数据点数量 t linspace(0, 2*pi, N); % 时间向量 width 12; % 位宽% 正弦波 sine_wave 2.5 * sin(t) 2.5; % 幅度在0到5之间% 三角波 tri_wave 5 - abs(mod(t/(2*pi)*4, 2) - 1);% 方波 square_wave 2.5 * (square(t) 1); % 将范围调…

Hive Tutorial For Beginners

Hive Tutorial For Beginners 一、Hive历史&#xff08;History of Hive&#xff09; Facebook 在面对日益增长的大数据时&#xff0c;选择了 Hadoop 作为解决方案。 但问题在于&#xff0c;许多用户并不熟悉 Java 或其他编程语言&#xff0c;这使得使用 Hadoop 的 MapReduc…

代码随想录——回文子串(Leetcode 647)

题目链接 我的题解&#xff08;双指针&#xff09; 思路&#xff1a; 当然&#xff0c;以下是对您提供的代码的解释&#xff1a; class Solution {public int countSubstrings(String s) {// 初始化回文子字符串的数量int count 0;// 遍历字符串的每个字符&#xff0c;使用…

无人机之电池篇

无人机电池作为无人机的重要组成部分&#xff0c;其性能、使用、保养及选择都至关重要。以下是对无人机电池的综合介绍&#xff1a; 一、无人机电池的基本参数 电池容量&#xff1a;电池容量直接影响无人机的续航能力。大容量电池&#xff0c;如5000mAh的电池&#xff0c;能提…

无人机道通布局的讲究详解!!!

一、通道分配与功能对应 基本通道&#xff1a;无人机遥控器通常至少包含四个基本通道&#xff0c;分别对应无人机的上下&#xff08;升降&#xff09;、左右&#xff08;副翼&#xff09;、前后&#xff08;俯仰&#xff09;和旋转&#xff08;方向舵&#xff09;控制。这些通…

关于报错 SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“ 的可能原因

1. 絮絮叨叨 学习或工作中&#xff0c;如果需要从头建立日志打印体系&#xff0c;笔者通常直接照抄之前的博客&#xff1a;《Java maven工程配置slf4j》&#xff0c;直接粘贴、复制相关依赖除了上述博客提到的slf4j-api、logback-classic&#xff0c;也看到过slf4j-simple、lo…

区域生长算法详解与Python实现

图像分割是计算机视觉中一个重要的任务&#xff0c;区域生长算法是其中的一种常见方法。本文将详细介绍区域生长算法的原理&#xff0c;并通过Python代码实现&#xff0c;带你一步步理解它的实际应用。 1. 区域生长算法简介 区域生长算法是一种基于像素相似性进行图像分割的方…

2025款宋L EV全面升级加量不加价,仅18.98万元起

8月30日&#xff0c;2024成都车展正式开幕&#xff0c;备受期待的比亚迪王朝网B级先锋猎装SUV——2025款宋L EV正式上市&#xff0c;搭载“天神之眼”高阶智能驾驶辅助系统DiPilot 100&#xff0c;e平台3.0、CTB、云辇-C三大明星技术&#xff0c;并新增外观内饰配色。凭借智驾、…

【2024】Datawhale X 李宏毅苹果书 AI夏令营 Task2

本文是关于李宏毅苹果书”线性模型“学习内容的记录。 线性模型 线性模型&#xff08;linear model&#xff09;&#xff1a;将输入的特征 x x x&#xff08;或 x \bold{x} x&#xff09;乘上权重 ω \omega ω&#xff08;或 ω \bold{\omega} ω&#xff09;&#xff0c;再…

Python简易IDE工作界面制作

、 休闲一下&#xff0c;学习编程还是要学习一些界面编程&#xff0c;能够根据需要制作图形操作界面&#xff0c;这样我们开发的程序才能方便操作和使用&#xff0c;同时获得更友好的人机交互体验。下面是一个用PyQt5制作的简易界面&#xff0c;供大学参考。如下图所示&a…

罪人的终幕(原题)

题目背景 而我承诺你&#xff0c;一切都将在一场盛大的&#xff0c;如同戏剧般的审判中结束…… 小小地旋转&#xff0c;轻轻地跳跃&#xff0c;然后便是「罪人」的谢幕。 题目描述 定义函数 &#x1d44e;(&#x1d465;)a(x) 表示自然数 &#x1d465;x 的不同的质因子的和。…

数据增强在Sentence Transformers中的作用:提高句子评分任务的性能

Sentence Transformers 是一个强大的 Python 库&#xff0c;它基于 Transformer 模型架构&#xff0c;如 BERT、RoBERTa 和 XLM-RoBERTa 等&#xff0c;用于学习和操作句子级别的向量表示。这个库特别适合于处理自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;能够为…

实用好软-----电脑端 开源的视频无损剪切与合并工具

这个是一个开源项目LosslessCut 无损剪切就是基于关键帧的剪切&#xff0c;不需要重编码&#xff0c;因此速度非常快&#xff0c; 缺点就是切割时间无法达到非常精确&#xff0c;可能前后会有几秒的差距&#xff0c; 要做到精确的剪切&#xff0c;只能重编码。 LosslessCut在切…

学习之SQL语句之DQL(数据库查询语言)

DQL英文全称是Data Query Language(数据查询语言)&#xff0c;数据查询语言&#xff0c;用来查询数据库中表的记录 查询关键字:SELECT 数据准备&#xff1a; CREATE TABLE emp ( id INT COMMENT “编号”, workno VARCHAR ( 10 ) COMMENT “工号”, NAME VARCHAR ( 10 ) COMME…

windows配置hadoop环境

目录 一、windows配置hadoop环境1、下载文件2、解压3、移动winutils.exe4、移动hadoop.dll5、配置代码内容 一、windows配置hadoop环境 1、下载文件 首先下载所需要的文件内容 共有三个文件&#xff0c;可以通过 这个链接 获得 2、解压 使用解压工具将 hadoop-3.0.0.tar.gz…

堆的时间复杂度分析

一&#xff0c;建堆的时间复杂度分析 堆是一颗完全二叉树&#xff0c;满二叉树又是一颗特殊的完全二叉树。 对于满二叉树来说&#xff0c;第一层的节点个数为2^0,第二层的节点个数为2^1,......所以可以得到第h层的节点个数为2^(h-1)。总结点个数N2^02^1...2^(h-1)2^h-1。那么就…