关于性能优化:百度-App-启动性能优化实践篇

一、前言启动性能是百度App最外围指标之一。用户心愿利用可能及时响应并疾速加载,启动工夫过长的利用不能满足这个冀望,并且可能会令用户悲观,这种蹩脚的体验可能会导致用户在利用商店针对您的利用给出很低的评分,甚至齐全摈弃您的利用。启动性能的优化成为了体验优化中最要害的一环,百度App在此方向继续投入,一直优化,晋升用户体验。 启动性能优化分为概述篇、工具篇、优化篇和防劣化篇,本篇文章次要论述性能优化相干内容,后期已发表文章能够参阅: 百度App 低端机优化-启动性能优化(概述篇) 百度App Android启动性能优化-工具篇 百度App性能优化工具篇-Thor原理及实际 二、优化实践对启动性能优化的认知,决定了启动性能优化的方向与思路,进而会决定优化的成果。较多开发者对启动过程的认知,来源于Google 开发者文档中有段对启动过程的形容: 1、创立利用对象; 2、启动主线程; 3、创立主 activity; 4、裁减视图; 5、布局屏幕; 6、执行初始绘制。 一旦利用过程实现第一次绘制,零碎过程就会换掉以后显示的后盾窗口,替换为主 activity。此时,用户能够开始应用利用。 下面次要介绍了利用在启动过程中的各个阶段,但其实只是大抵概括,其实启动形式会比拟多,极有可能在不同的启动门路执行的逻辑有差别,因而全门路的认知在优化过程中起到了十分重要的作用,如下图所示: 在启动过程中,点击桌面图标是支流冷启动形式,而Push调起,浏览器调起等端外转化也是比拟常见的调起形式,各种启动形式的启动过程根本可拆解为:过程创立、框架加载、首页渲染、预加载四个环节。而启动性能优化次要面对的不只是点击桌面图标这一种门路,更多的须要启动全门路的优化,达到体验的极致优化。 启动过程也须要联合零碎层面来了解,进而开掘优化点,摸索优化的极限。启动过程是非常复杂的过程,须要较多零碎级过程配合能力实现页面的展示,供用户失常应用,下图展现的点击icon的启动过程: 启动过程大略可概括为: 1、Launcher告诉AMS启动APP的主Activity; 2、ActivityManagerService(以下简称AMS)记录要启动的Activity信息,并且告诉Launcher进入pause状态; 3、Launcher进入pause状态后,告诉AMS曾经paused了,开始启动App; 4、App未开启过,AMS启动新的过程,并且在新过程中创立ActivityThread对象,执行其中的main函数办法; 5、App主线程启动结束后告诉AMS,并传入applicationThread以便通信; 6、AMS告诉App绑定Application并启动MainActivity; 7、启动MainActivitiy,并且创立和关联Context,最初调用onCreate办法,最终实现页面绘制和上屏。 次要过程的性能次要是: 1、Launcher过程:为手机桌面过程,负责接管用户的点击事件,并将事件告诉到AMS 2、SystemServer过程:负责利用的启动流程调度、过程的创立和治理、窗口的创立和治理(StartingWindow 和 AppWindow) 等,比拟外围的服务有AMS和WMS(WindowManagerService); 3、Zygote过程:通过fork创立应用程序过程,Zygote过程在初始化时就会会创立虚拟机,同时把须要的零碎类库和资源文件加载到内存中。而Zygote在fork出子过程后,这个子过程也会失去一个曾经加载好根底资源的虚拟机,从而减速利用过程的启动; 4、SurfaceFlinger过程:次要和利用的渲染相干,如Vsync信号处理、窗口的合成解决、帧缓冲区治理等。 有了全局的认知和视线后,咱们就能够站在更高的角度,更加深刻的思考与剖析性能瓶颈,如手机负载合理性、系统资源应用等等,更加全面的思考启动性能的优化形式,达到对启动性能的极致优化。 三、优化落地百度App的启动性能的优化,大抵分为三局部,惯例优化、根底机制优化和底层技术优化三局部。 3.1 惯例优化如果是业务倒退初期,业务的疾速迭代较快,此时的优化会绝对简略,极有可能会呈现短时间内,启动速度晋升秒级别的优化成果。启动性能的优化,也是基于对冷启动的了解以及启动工作的梳理,达到疾速优化的指标。可通过性能工具,如前文提过的Trace工具、Thor Hook工具,发现耗时较为突出问题,评估是否可通过提早、异步、删除等形式优化,根据投入产出状况评估工作优先级,达到疾速优化启动性能的目标。 随着启动场景承载业务逐渐宏大,手百逐步成长为承载业务最多,体量微小的航母级挪动端利用,宏大业务的预加载不可能齐全去除或者通过异步来解决,此局部是启动性能优化中面临的较大难题,须要有机制批量解决业务预加载问题,因而根底机制中的调度机制逐步衍生进去,解决启动过程不同业务的预加载需要。 3.2 根底机制优化根底机制优化次要分为调度机制优化、根底组件性能优化。 3.2.1 任务调度优化业务多,预加载工作的执行诉求各有不同,均衡启动性能和业务预加载,百度App需建设任务调度框架,业务方通过接入可疾速优化性能问题。 任务调度整体建设状况如下,目前还处在疾速迭代中: 智能调度能够依据工作输出和信息输出,做出不同的调度反馈,如: 1、个性化调度策略:辨认出业务预加载工作ID和用户行为习惯相匹配,则会将工作提前做初始化,工作优先级会做晋升,与此同时,在用户进入业务对应页面时,非业务相干工作需做避让; 2、分级体验策略:辨认出在指定的机型配置中有对应的调度策略,则会执行对应的调度能力,如立刻调度、提早调度、不调度等,次要用于体验降级; 3、精细化调度策略:在不同的场景精细化调度业务预加载工作,如在闪屏场景,会辨认闪屏相干业务信息并做预加载,在端内查起场景,会辨认落地页所属业务信息并做对应预加载; 4、分优先级提早调度:有较大量的工作初始化会依赖于提早调度,需保障有序管制业务初始化,因而在提早调度根底上增加优先级概念,能够在提早调度中也分优先级调度,让更高优先级工作能够更快的执行; 5、首页UI并行渲染调度:次要服务于冷启动阶段商业闪屏业务,商业闪屏是否须要展示、展示哪个物料均是冷启动阶段的实时网络申请决定的,需在冷启动阶段尽量进步商业网络申请的可用工夫,进而进步网络申请成功率,百度App目前能够实现,首页能够先初始化,但不做上屏,待首页渲染业务提交的时候再查看商业闪屏是否展示,做到了提供给商业网络申请更多可用工夫的同时不阻塞首页初始化,通过此项技术大幅晋升商业网络申请的成功率,带来了商业支出的晋升。 因为调度器框架中波及细节十分多,在这里只简略介绍其中一种调度器的设计:分级体验调度器。 次要分为3个模块,机型评分、分级配置和分级调度机制,达到不同配置的手机上的最优体验。 机型评分:通过设施信息计算评分信息,称为动态评分;通过性能指标计算评分信息,称为动静评分;根据模型训练评分信息,得出最终机型评分;分级配置:云端配置表:提供各业务级别按设施评分条件下的分级配置表,该表反对动静更新,增量更新,更新后端上及时失效。本地预置表:本地会预置一份配置表,供首次装置时应用;根据机型评分信息和分级配置信息得出控制策略;分级调度:业务方依据机型评分管制不同的业务逻辑,达到高端机全副性能最优体验,中端机局部性能良好体验,低端机外围性能晦涩体验,如首页点赞动画在高端机上抉择开启策略,中端机上抉择提早加载策略,低端机上抉择敞开状态;3.2.2 KV存储优化SharedPreferences是Android平台轻量级的存储类,用来保留应用程序的配置信息,其本质是以“键-值”对的形式保留数据的xml文件,其文件保留在/data/data/pkg/shared\_prefs目录下,长处是以键值对的形式进行存储,使用方便,易于了解;但SharedPreferences的毛病很显著,读写性能慢,IO读写应用xml数据格式,全量更新效率低;多过程反对差,存储数据易失落;创立线程多,导致性能差。 读取性能差 每加载一个SP文件均会创立子线程,源码如下: private final Object mLock = new Object();private boolean mLoaded = false;private void startLoadFromDisk() { synchronized (mLock) { mLoaded = false; } new Thread("SharedPreferencesImpl-load") { public void run() { loadFromDisk(); } }.start();}然而在获取key-value时如果没有加载实现,则会wait期待SP文件加载实现: ...

July 11, 2023 · 2 min · jiezi

关于性能优化:研发质量指标大-PKMTTR-vs-MTBF谁是靠谱王

在研发品质治理中,「进步代码/测试品质」更重要,还是「晋升故障响应能力」更重要?LigaAI 最近和一些敌人探讨了这个问题。一种观点认为晋升研发品质应该从代码品质抓起——擒贼先擒王,从源头缩小故障产生才是基本之道; 另一种声音则指出,生产故障简直不可能通过预防完全避免,因为「未知」是无奈预测的,因而增强监测与反馈机制,疾速辨认、疾速修复才是真正的无效之治。 从治理指标的角度来看,「晋升代码品质」意味着研发团队要尽可能进步 MTBF(均匀无故障工夫),缩短零碎可继续运行工夫,而「晋升响应能力」要求尽可能减少 MTTR(均匀复原工夫),将零碎不可用工夫降到最短以最小化故障影响。 舒适提醒:研发团队该当先全面探讨零碎「服务工夫」「可用工夫」和「不可用工夫」的定义、事件覆盖范围以及故障等级,并在组织外部建设对立的了解,以确保资源和精力花在最重要的事件上。只管在理论工作中,「进步 MTBF」和「缩小 MTTR」总是齐驱并进,但在不同倒退阶段明确二者的优先级,将有助于研发团队高效专一、对症下药地实现研发效力治理指标。 MTBF 和 MTTR 将如何影响研发效力?咱们先从研发品质治理的三个维度说起。 01 研发品质治理的「RAM」在治理实际中,咱们罕用「RAM」评估软件交付性能。这里的「RAM」当然不是 Random Access Memory,而是三个用于形容零碎服务质量高下的要害维度——可靠性、可用性和可维护性。 1. 可靠性 Reliability 可靠性是指零碎无故障运行的能力——哪怕呈现软硬件故障、人为谬误等问题,零碎仍能失常提供正确服务而不产生服务中断的概率。 它与故障率、容错率、避错力、冗余度等严密相干。常见的软件可靠性度量指标包含牢靠度、失效率、MTBF 和 MTTF 等等。 2. 可用性 Availability 可用性是指在肯定工夫内,零碎可能继续且正确提供合乎冀望水准的服务而不产生故障和中断的概率,通常用 SLA(Service Level Agreement,服务级别协定)来示意。 零碎可用性(或称可用度)能够用零碎可用工夫占总服务工夫的百分比计算得出,即 3. 可维护性 Maintainability 可维护性蕴含可修复性和可改良性两个方面。前者是指在零碎产生故障后,不同人员高效修复故障,使之恢复正常运行状态的难易水平,而后者示意当需要或环境变动时,零碎承受性能改良或减少新性能的可能性。 可靠性和可用性都能够展现零碎的继续服务能力。区别在于,可用性更加关注零碎服务的总体持续时间,而可靠性侧重于形容零碎的抗故障能力。《分布式系统原理与范型》为辨别可靠性和可用性提供了一个十分直观的例子: 如果零碎在每小时解体 1 ms,那么它的可用性就超过 99.9999%,然而它还是高度不牢靠。与之相似,如果一个零碎从来不解体,然而每年要停机两星期,那么它是高度牢靠的,然而可用性只有 96%。02 如何确定 MTBF 和 MTTR 的优先级?对于不同组织或者同一组织的不同倒退阶段,晋升研发品质的无效伎俩很可能截然不同。那么,是否存在某种范式,能够帮忙研发团队迷信精准地确定 MTBF 和 MTTR 的治理优先级? 后面提到,可用性的计算公式可示意为零碎可用工夫占总服务工夫的比重,即 MTBF / (MTBF + MTTR)。简略变形后,便能够取得以下关系式: ① MTBF = 可用性 * MTTR / (1 - 可用性) ...

July 5, 2023 · 1 min · jiezi

关于性能优化:性能优化之windowonload

前言最近在做一些性能优化相干的工作,置信大家在工作过程中也会遇到一些性能优化相干的场景,这对于前端开发者来讲是一项加分技能。为了咱们的用户在应用咱们的产品时可能有一个十分好的体验,咱们须要对页面进行诊断优化。在行业中,咱们的页面P90在两秒内算是达标,超过这个工夫那么你就可能会散失局部用户。 TIP:P90指的是页面性能数据从小到大排序,在90%地位的数据。 比方:P90为两秒,那它的意思就是90%的用户都可能在两秒内关上页面 对于性能优化内容可能比拟多,咱们这里就先着重理解window.onload相干内容。对于页面加载时长,咱们就防止不了波及window.onload。 性能剖析做性能优化必定免不了须要对页面性能进行剖析,咱们个别会应用ChromeDevTool作为根底的性能剖析工具,察看页面性能状况 Network:察看网络资源加载耗时及程序 Performace:察看页面渲染体现及JS执行状况 Lighthouse:对网站进行整体评分,找出可优化项 明天咱们先着重来看Network的相干内容,比方咱们关上浏览器控制台: 这里咱们能够看到这两项数据:DOMContentLoaded工夫为841ms、Load工夫为2.06s 它俩别离对应两个事件: DOMContentLoaded当初始的 HTML 文档被齐全加载和解析实现之后,DOMContentLoaded 事件被触发,而无需期待样式表、图像和子框架的齐全加载。Loadload 事件在整个页面及所有依赖资源如样式表和图片都已实现加载时触发。它与 DOMContentLoaded 不同,后者只有页面 DOM 加载实现就触发,无需期待依赖资源的加载。看完两者的解释之后,置信大家应该明确了为什么Load花的工夫要比DOMContentLoaded长了吧 因为load事件会被大量媒体资源阻塞,浏览器只有在它认为页面上的所有资源都加载实现了才会触发load事件。 两者的区别DOM残缺的解析过程: 解析HTML加载内部脚本与款式文件解析并执行脚本DOM树构建(DOMContentLoaded事件触发)加载图片等资源页面加载结束(Load事件触发)DOM的解析受JS加载和执行的影响,咱们在优化时应尽量对JS进行压缩、拆分解决(HTTP2下),能缩小 DOMContentLoaded 工夫图片、视频、CSS等资源,会阻塞 onload 事件的触发,咱们在优化过程中须要优化资源的加载机会,让load事件尽快触发深刻了解window.onloadonload触发机会JS 加载并执行结束且页面中所有外链资源加载实现之后大概 3 - 4ms(这个值跟机型和浏览器无关)比方: window.onload = () => { console.log('load')}setTimeout(() => { console.log('timeout')}, 3)后果是setTimeout先执行,这里把值改的稍大一点你会发现就是load先执行了 哪些因素会影响window.onloadJS执行window.onload = () => { console.log('load')}for(let i = 0; i < 100000; i++) { console.log(i)}当咱们写了一个十分耗时的JS工作时,你会发现DOMContentLoaded与Load事件都会等很久才会触发。 阐明JS的执行不仅会阻塞DOMContentLoaded事件的触发,也会阻塞Load事件的触发。所以在优化过程中,JS也是一个重点关注对象。 async异步加载脚本<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.47/vue.cjs.js" async></script><script src="https://cdn.bootcdn.net/ajax/libs/Chart.js/4.2.1/chart.js"></script>为了比照,这里我加载了两个JS文件,一个应用async异步加载,一个间接加载,咱们再到控制台来查看此时的加载状况。 这里咱们能够看到两个文件都是在Load之前就会加载,只不过应用了async异步加载会比失常加载的后加载,阐明应用了async异步加载脚本仍然会阻塞Load的触发。 对于async的解释MDN上是这样说的: 对于一般脚本,如果存在 async 属性,那么一般脚本会被并行申请,并尽快解析和执行。 对于模块脚本,如果存在 async 属性,那么脚本及其所有依赖都会在延缓队列中执行,因而它们会被并行申请,并尽快解析和执行。 ...

July 3, 2023 · 1 min · jiezi

关于性能优化:微信海量数据查询如何从1000ms降到100ms

腾小云导读 微信的多维指标监控平台,具备自定义维度、指标的监控能力,次要服务于用户自定义监控。作为框架级监控的补充,它承载着聚合前 45亿/min、4万亿/天的数据量。以后,针对数据层的查问申请也达到了峰值 40万/min,3亿/天。较大的查问申请使得数据查问遇到了性能瓶颈:查问均匀耗时 > 1000ms,失败率居高不下。针对这些问题,微信团队对数据层查问接口进行了针对性的优化来满足上述场景,将均匀查问速度从1000ms+优化到了100ms级别。本文为各位分享优化过程,心愿对你有用! 目录 1 背景介绍 2 优化剖析 2.1 用户查问行为剖析 2.2 数据层架构 2.3 为什么查问会慢 3 优化方案设计 3.1 拆分子查问申请 3.2 拆分子查问申请+Redis Cache 3.3 更进一步-子维度表 4 优化成绩 4.1 缓存命中率>85% 4.2 查问耗时优化至 100ms 5 结语 01、 背景介绍微信多维指标监控平台(以下简称多维监控),是具备灵便的数据上报形式、提供维度穿插剖析的实时监控平台。 在这里,最外围的概念是“协定”、“维度”与“指标”。例如,如果想要对某个【省份】、【城市】、【运营商】的接口【错误码】进行监控,监控指标是统计接口的【均匀耗时】和【上报量】。在这里,省份、城市、运营商、错误码,这些形容监控指标属性的可枚举字段称之为“维度”,而【上报量】、【均匀耗时】等依赖“聚合计算”后果的数据值,称之为“指标”。而承载这些指标和维度的数据表,叫做“协定”。 多维监控对外提供 2 种 API: 维度枚举查问:用于查问某一段时间内,一个或多个维度的排列组合以及其对应的指标值。它反映的是各维度散布“总量”的概念,能够“聚合”,也能够“开展”,或者固定维度对其它维度进行“下钻”。数据能够间接生成柱状图、饼图等。工夫序列查问:用于查问某些维度条件在某个工夫范畴的指标值序列。能够展现为一个时序曲线图,横坐标为工夫,纵坐标为指标值。然而,不论是用户还是团队本人应用多维监控平台的时候,都能感触到显著的卡顿。次要体现在看监控图像或者是查看监控曲线,都会通过长时间的数据加载。 团队意识到,这是数据量回升必然带来的瓶颈。目前,多维监控平台曾经接入了数千张协定表,每张表的特点都不同。维度组合、指标量、上报量也不同。针对大量数据的实时聚合以及 OLAP 剖析,数据层的性能瓶颈越发显著,重大影响了用户体验。于是这让团队人员不由得开始思考:难道要始终放任它慢下去吗?答案当然是否定的。因而,微信团队针对数据层的查问进行了优化。 02、 优化剖析2.1 用户查问行为剖析要优化,首先须要理解用户的查问习惯,这里的用户蕴含了页面用户和异样检测服务。于是微信团队尽可能多地上报用户应用多维监控平台的习惯,包含但不限于:罕用的查问类型、每个协定表的查问维度和查问指标、查问量、失败量、耗时数据等。 在剖析了用户的查问习惯后,有了以下发现: 【工夫序列】查问占比 99% 以上呈现如此迥异的比例可能是因为:调用一次维度枚举,即可获取所关怀的各个维度。然而针对每个维度组合值,无论是页面还是异样检测都会在查问维度对应的多条工夫序列曲线中,从而呈现「工夫序列查问」比例远远高于「维度枚举查问」。 针对1天前的查问占比约 90%呈现这个景象可能是因为每个页面数据都会带上几天前的数据比照来展现。异样检测模块每次会比照大概 7 天数据的曲线,造成了对大量的非实时数据进行查问。 2.2 数据层架构剖析完用户习惯,再看下目前的数据层架构。多维监控底层的数据存储/查问引擎抉择了 Apache-Druid 作为数据聚合、存储的引擎,Druid 是一个十分优良的分布式 OLAP 数据存储引擎,它的特点次要在于杰出的预聚合能力和高效的并发查问能力,它的大抵架构如图: 节点解析Mater节点Overlord:实时数据摄入生产控制器Coordinator:协调集群上数据分片的公布和负载平衡实时节点MiddleManager:实时数据写入两头管理者,创立 Peon 节点进行数据生产工作并治理其生命周期Peon:生产实时数据,打包并公布实时数据分片存储节点Historical:存储数据分片 DeepStorage:分片直达存储,不对外查问 MetaDataStorage:元信息,如表构造 Zookeeper:存储实时工作和状态信息2.3 为什么查问会慢查问慢的外围起因,经微信团队剖析如下: ...

June 2, 2023 · 2 min · jiezi

关于性能优化:京东购物车如何提升30性能-京东云技术团队

1、背景 购物车面临的挑战: 1)新业务:随着业务状态的丰盛,购物车在一直反对各种新业务,依赖的内部接口也随之减少; 2)下沉:一些前端调用的接口下沉到购物车中台; 3)前置:结算流程很多业务前置到购物车中,如优惠券、京豆; 4)扩容:为改善用户体验购物车可包容的商品数量在一直增长; 这些导致购物车依赖的RPC接口数量及分页调用次数都在一直减少。购物车作为交易流程开始,自身流量较大,在业务复杂化的背景下,如何进步性能保障用户体验,成为购物车面临的较大挑战。 2、全异步化革新计划通过减少服务器资源尽管能在肯定水平上解决问题,但会带来较大的老本开销,也与工匠精力相悖。是否通过技术手段晋升性能呢?通过剖析,异步化革新成为解决这一问题的无效伎俩。 1)不同RPC并行 购物车依赖接口达几十个,各接口间存在简单依赖关系。必须先梳理各接口间依赖,辨认哪些能够并行。而后将原有代码拆分为两局部:RPC异步申请和后果解决,依照依赖关系,让RPC最大限度并行执行,缩小在后果解决阶段异步响应等待时间,从而达到晋升性能的目标。 2)批量接口多分页并行 购物车依赖接口多为批量接口,且单次调用有数据量限度,需将数据拆分为多个分页调用。那么多个分页间也能够并行,革新中封装了异步分页工具,使业务层对分页逻辑无感知,异步工具主动将超过接口下限的数据拆分为多个分页并行调用,晋升单接口响应速度。 3)底层采纳JSF异步调用 异步调用基于京东RPC框架JSF,举荐应用1.7.5当前版本,反对CompletableFuture。 3、问题及解决异步化革新的总体方案并不简单,然而在理论落地过程中,遇到了很多细节问题: 1)异样重试需精细化 同步调用时,如果超时会从新调用。改为异步后重试会生效,因为在调用时个别不会报错,须要在后果解决阶段获取异步响应超时后,再进行重试。 另外,多分页并行时,当某一页申请超时后,应该只重试出错的分页。底层对分页调用进行了封装,下层业务代码在获取数据时无奈感知是哪一页超时,所以必须在异步调用时将现场信息保留在包装类中,一起返回给业务层,在Get数据超时后,独自重试出错的分页。 产生异样时,并不是所有状况都须要重试,当遇到限流等异样时,不能进行重试。底层工具须要主动过滤限流异样,当然也反对自定义规定。 2)异步RPC监控更简单 底层RPC耗时监控须要拆分为两局部,在分页调用时记为开始工夫,在异步后果达到后,记为完结工夫。如果调用异样或Get超时,须要标记本次调用失败。对于重试同样须要记录调用耗时,且失常调用与重试调用需离开记录。 除了须要监控RPC耗时外,还须要监控后果解决阶段Get期待时长,这个工夫才是真正对利用性能有影响的工夫。因为底层是分页调用,所以业务调用次数和底层RPC调用次数并不相同。 3)分页异步后果不能合并,否则无奈获取异样Provider信息 底层异步调用后果,必须通过包装类原样返回给下层,除了上边提到的须要单分页重试外,另一个起因是必须保留异步后果,在分页超时后能力输入超时的Provider信息。这是因为Provider信息依赖JSF框架的JSFCompletableFuture,如果在底层合并后果,会导致信息失落。 4)每页超时工夫需独自管制 分页调用过程如上图所示,在后果解决时,每页Get超时工夫须要独自管制,因为获取后果是程序进行,获取后边的分页时,前边分页期待的工夫也应计算在内,以保障整个获取后果的工夫不超过单个分页的最大超时工夫。计算公式如下: 超时=RPC超时工夫 > (以后工夫-异步调用开始工夫) ? RPC超时工夫 – (以后工夫-异步调用开始工夫) : 0 5)分页平衡 为防止最初一页数据过少造成数据歪斜,须要将申请数据均分到每一页,以最大限度进步整个申请的性能。 4、收益革新实现后购物车外围接口耗时缩小30%,保障用户体验,节俭大量服务器资源。后续减少新的RPC接口时,只有处在调用拓扑的非关键门路上,对购物车性能没有太大影响。另外,容量减少时除少数不能分页调用的接口外,对性能影响曾经比拟小。 作者:京东批发 王利辉 梁奉龙 内容起源:京东云开发者社区

May 23, 2023 · 1 min · jiezi

关于性能优化:rt下降40程序并行优化六步法-京东云技术团队

1 背景性能优化是咱们日常工作中很重要的一部分,次要有以下起因: 升高服务器和带宽等硬件老本:用更少的资源解决更多的申请进步事实世界的运行效率:人机处理效率存在数量级的偏差,同样机器世界的效率晋升能带来事实世界效率晋升的办法成果进步用户的体验:解决响应迟缓、宕机等问题而并行优化在改善程序接口响应工夫和吞吐量指标方面是个利器,所以本次联合前段时间做的一段长链路执行逻辑代码的优化,给大家讲讲程序并行优化的步骤及方法论。 2 多线程优化六步法2.1 定位优化点个别是通过全链路监控、火焰图、自定义打点、生产报警等先找到耗时长的性能问题点,之后通过多线程并行化的形式达到优化程序响应时长和吞吐量的目标。 2.2 执行链路剖析对问题点的执行链路进行剖析,次要分几方面: 链路里波及的操作节点;节点本身的耗时;是io密集型还是cpu密集型;是否依赖和批改内部变量;此节点是否是外围门路;节点间彼此依赖关系;2.3 异步链路设计将链路依据依赖关系进行重排,把被依赖的放在后面;彼此不依赖有雷同终点的节点并行化;设计并行任务后果获取及后续依赖节点的告诉机制如果有指定响应工夫指标的链路,为外围门路节点设计降级计划;依据响应工夫要求及已耗时数据对非核心门路节点调用进行舍弃;将对变量批改的逻辑收拢,且尽量在主线程中解决,防止须要做的多线程变量可见性和时序性同步2.4 并发框架抉择1.线程池 形容:具体业务工作继承接口 Runnable、Callable ,在调用 ExecutorService.submit 接口时,会提交工作到 ExecutorService 外部的一个工作队列中。同时,在 ExecutorService 外部还存在一个事后申请的线程池(Thread Pool),线程池中的线程会从工作队列中支付一个工作来执行。 长处:复用线程,缩小线程创立销毁老本及缩小申请时延 留神点:cpu密集型和io密集型工作应进行不同的线程池配置;为防止不同工作互相烦扰重要业务最好独立应用线程池;不同线程之间要留神操作的有序和数据的可见性 2.AKKA 形容:每个 Actor 代表的是能够被调度执行的轻量单元。如图中所示,Actor A 和 Actor C 在向 Actor B 发送音讯时,所有音讯会被底层框架发送到 Actor B 的 Mailbox 中,而后底层的 Akka 框架调度代码会触发 Actor B,来接管并执行音讯的后续解决。这样,基于 Actor 模型的这套并发框架,首先就保障了音讯能够被平安地在各个 Actor 之间传递,同时也保障了每个 Actor 实例能够串行解决接管到的所有音讯。 长处:不须要关注多线程之间并发同步和数据一致性;轻量级高并发 留神点:actor工作粒度要小,防止承接太多业务逻辑;计算密集型工作更能施展出AKKA的劣势 3.REACTOR 形容:输出流 Flux 就是 Reactor 中典型的异步音讯流,它代表了一个蕴含 0 个到 N 个的音讯序列。另外,图中的 Rule 代表的是一个基于音讯的解决逻辑或规定,输出流中的音讯能够被两头多个解决逻辑组合间断加工之后,再生成一个蕴含 0 个到 N 个的输入音讯流 Flux。 ...

May 22, 2023 · 1 min · jiezi

关于性能优化:实践指南前端性能提升-270

一、背景当咱们疲于开发一个接一个的需要时,很容易遗记去关注网站的性能,到了某一个节点,猛地发现,随着越来越多代码的沉积,网站变得越来越慢。 本文就是从这样的一个背景登程,着手优化网站的前端性能,并总结出一套开发习惯,让咱们在日常开发时,也放弃高性能,而不是又一次回过头来优化性能。 先来看看优化的成绩,Lighthouse 的 Performance 评分共计晋升 279%: 指标名称优化前优化后晋升Lighthouse Performance 评分2981279%FCP(First Contentful Paint 首次内容绘制)0.7s0.7s LCP(Largest Contentful Paint 最大内容绘制)6.2s2.5s248%TTI(Time to Interactive 可交互工夫)10.1s2.1s480%Speed Index(速度指数)5.6s1.8311%TBT(Total Blocking Time 总阻塞工夫)820ms120ms683%优化前后比照: 二、优化前接下来就是介绍下优化前咱们要做哪些事件: 理解性能指标及测量工具剖析须要优化的中央1. 理解测量工具及性能指标一开始咱们只是感触到网站的页面关上时白屏工夫较长,感觉性能是比拟差的,那么具体有哪些性能指标须要去关注呢? 这里我应用的是 Chrome devtools 内置的 Lighthouse,Lighthouse 是一种开源的自动化工具,用于进步 Web 应用程序的品质。 Lighthouse 会在一系列的测试下运行网页,比方不同尺寸的设施和不同的网络速度。它还会查看页面对辅助性能指南的一致性,例如色彩对比度和 ARIA 最佳实际。 关上 Chrome devtools Lighthouse 即可应用。 在比拟短的工夫内,Lighthouse 能够给出这样一份报告。 这份报告从 5 个方面来剖析页面: 性能、辅助性能、最佳实际、搜索引擎优化和 PWA。像性能方面,会给出一些常见的耗时统计。 1.1 PerformancePerformance 评分统计,包含了以下指标: 1.1.1 FCPFCP 测量在用户导航到页面后浏览器出现第一段 DOM 内容所破费的工夫。页面上的图像、非红色<canvas>元素和 SVG 被视为 DOM 内容;不包含 iframe 内的任何内容。 1.1.2 LCPLCP 测量视口中最大的内容元素何时出现到屏幕上。这近似于页面的次要内容对用户可见的工夫。 ...

April 13, 2023 · 2 min · jiezi

关于性能优化:你需要同款Unreal项目自动化编译打包和部署方案吗

在过往几期的UWA Pipeline最佳实际案例中,咱们分享了如何通过Pipeline实现性能优化、性能治理、游戏内容验收和云真机系统的利用(实现批量真机设备的自动化测试,以及针对特效性能优化的形式),其实这些高效的办法并不局限游戏引擎。明天,分享一篇来自广州钛壳树的UWA Pipeline应用心得,这是一家致力于发明独特原创IP、专一Unreal研发的游戏公司,看看UWA Pipeline如何帮忙Unreal研发团队达到锦上添花的成果。 常态化的引擎自动化编译、客户端主动打包、服务器继续部署,这是钛壳树团队在Unreal我的项目研发的过程中,应用UWA Pipeline实现的三大性能,大幅简化了工作流程,节俭了人力与工夫,进步了CI/CD的执行效率。以下分享出自钛壳树团队CEO的自述,具体介绍了具体实现的思路和形式,供宽广有相似需要的Unreal团队参考。 一、Unreal引擎主动编译的实现咱们应用Windows作为流水线节点,通过流水线的简略操作,疾速无效地实现不同的构建需要;通常UE引擎都有比拟严格的运行环境和编译条件,借助流水线和联结编译IncrediBuild能极大进步构建效率,升高构建复杂度,缩小人工干预的次数。 研发过程中批改Unreal引擎源码是必不可少的。获取源码后,除了有利于了解引擎的运行机制和不便调试,更多的是能够对引擎进行个性化定制,从而加强我的项目的游戏成果和可玩性。在构建流水线之前,大家能够通过Pipeline设置中的环境变量,来预设工作目录和工程门路,不便在后续的步骤中调用。 咱们的引擎编译流水线如下图所示,次要包含“Init”、“UpdateRepos”、“BuildAndCook” 和“CommitRepos”四个阶段。 每个阶段的具体作用为: 第一阶段 Init 确保编译环境洁净、当前任务独占相干资源。如此运算力资源可能充分利用,并且能够防止资源占用抵触导致的报错。咱们的做法是:初始化环境、确保没有手动关上的编译过程。同时将节点的并发构建数量设置为1,确保不会有多个工作并发执行。 第二阶段 UpdateRepos 进入预设的工作目录,通过Git和凭证治理,更新位于外部Gitlab的引擎源码ue_tree。 第三阶段 BuildAndCook 编译引擎。进入工作目录调用VisualStudio编译命令,对引擎工程进行命令行编译,对应的批处理脚本如下: 通常编译引擎会占用很多CPU算力资源,须要破费很长时间能力实现编译,所以非必要状况下不执行Rebuild操作。咱们在这里通过Pipeline的参数化构建性能,在流水线上设定选项参数,提供多种编译形式(Build和Rebuild),在执行时,就能够将参数传递给编译器以明确编译模式。 第四阶段 CommitRepos 把最新的引擎提交到SVN,用于接下来的开发工作。引擎编译后会生成若干目录,其中蕴含引擎运行所需的DLL、执行程序以及两头文件。这里大家须要辨别两头文件的内容,防止把不必要的文件上传到SVN仓库中。 二、Unreal客户端主动打包的实现实现引擎编译后,接下来就是对游戏客户端进行编译打包。日常的继续构建,可能不便咱们随时跟进游戏研发进度,体验游戏的个性和玩法。Unreal客户端打包时,大家须要留神引擎版本的应用,将官网版本和自定义版本区别开,免得成果不合乎预期。 咱们的打包流水线如下图所示,次要包含“Init”、“UpdateRepos”、“StartBuild”、“BuildAndCook”和“Commit”五个阶段。 每个阶段的具体作用为: 第一阶段 Init 与编译引擎的解决形式统一,确保工作独占编译资源,保障后续步骤顺利进行。 第二阶段 UpdateRepos 获取最新的代码和资源。游戏客户端除了波及开发代码和脚本外,还须要有数据资源,包含蓝图、配置数据、材质、模型、场景等等。其中代码和脚本应用Gitlab治理,数据资源应用SVN治理。 在打包的时候,大家须要再创立一个新的工作目录,把最新获取的代码和资源都拷贝到工作目录中,进行独立编译。 第三阶段 StartBuild 执行编译前的筹备工作。设定工程应用的引擎版本,在开发时是通过右键菜单进行抉择,在流水线中则应用VersionSelector.exe命令解决。 抉择引擎后须要对工程生成对应的编译工具,包含:UnrealPak、Bootstrap、CrashReport以及工程,命令如下。 第四阶段 BuildAndCook 将游戏工程生成最终能运行的程序或安装包。其中,Build执行的是针对所选平台编译二进制可执行文件;Cook是针对指标平台,将所援用的资源转换成对应的运行时格局。开始构建前,预设生成指标门路和两头目录,确保生成后的目录无效,给予下阶段应用。 第五阶段 Commit 提交构建后果到云空间。咱们在开发阶段不论是手动还是每天主动构建,都会依照日期寄存到公司外部的云空间中,不便开发人员获取和验证。 联合Gitlab实现提交时触发构建 UWA Pipeline提供了近程构建性能,激活流水线设置中的近程构建,流水线会生成一个URL地址,咱们通过不同的参数配置触发流水线中对应的编译模式,达到和手动抉择参数一样的成果。 通过Gitlab的Webhooks填写对应的URL地址,通常在代码仓库PR时,就能够主动触发流水线运行,从而放慢构建和部署的频率,进步开发效率。 三、服务器继续部署的实现咱们应用Linux作为流水线的节点,用于外部游戏服务的主动构建和部署,实现继续集成。 游戏服务是一个组件集群,波及到多个过程和依赖,为了进步构建速度、升高部署复杂度,通常反对一键部署。同时为了保障构建工作的互斥和步骤程序的正确,倡议大家将节点的并发构建数设为1。同时,至于针对不同测试目标,须要在同一个节点进行继续集成。这就须要通过服务隔离、运行端口调配、第三方组件和应用容器部署等形式,实现多份服务过程的部署。Pipeline零碎设置-阶段治理-阶段设置内能够配置节点的并发构建数,限度节点上能运行的工作数量 在单机部署测试环境中,将Linux作为流水线运行的节点时,还须要大家提前配置相干的数据库、缓存以及游戏服务所需的运行环境,咱们能够通过容器形式实现疾速配置。 咱们的服务器部署流水线如下图所示,次要包含“Update”、“Build”和“Reboot”三个阶段。 每个阶段的具体作用为: 第一阶段 Update 从外部Gitlab拉取最新代码(C/C++、Lua)和资源配置(Lua、JSON)。通过应用流水线提供的凭证治理和Git组件,在预设的工作目录中取得最新的代码和资源。 咱们在构建之前,通过Pipeline流水线设置,增加了选项参数或文本参数,设置版本指标和操作类型,不便后续在执行部署时可能依据需要进行构建。 第二阶段 Build 进入工程目录,编译Framework、依赖库和游戏代码,生成so文件和脚本文件。 第三阶段 Reboot 依据预设的指标参数,从编译工作目录中把执行程序、so文件、脚本复制到指标运行目录,进行运行过程中的游戏服务并重启。 定时构建 通过Pipeline提供的主动构建形式,设定好构建触发器,依据需要设定主动构建的频率,就能够在无人值守的状况下,实现流水线的定时主动构建。咱们现阶段的服务器构建仅限用于内部测试服应用,固定是每天构建一次。 感激钛壳树团队的精心分享,有雷同需要的Unreal团队都能够参考和借鉴。如果你被这个团队CEO的能力和态度所感动,违心退出广州钛壳树的话,现凋谢UE4引擎开发工程师、UE4特效设计师等岗位,小编也十分乐意为你推荐。再次感激钛壳树团队对UWA的认可,在游戏行业工业化倒退的路上咱们又独特迈进了一步。 更多UWA Pipeline应用案例分享能够查看: 《乐享元游的 UWA Pipeline 最佳实际分享》《一款ARPG游戏是如何搭建云真机系统的》《再也不必焦虑特效造成的性能问题了》 ...

March 1, 2023 · 1 min · jiezi

关于性能优化:什么后端要一次性返回我10万条数据且看我这8种方案机智应对

问题形容面试官:后端一次性返回10万条数据给你,你如何解决?我:歪嘴一笑,what the f**k! 问题考察点看似无厘头的问题,实际上考查候选人常识的广度和深度,尽管在工作中这种状况很少遇到... 考查前端如何解决大量数据考查候选人对于大量数据的性能优化考查候选人解决问题的思考形式(对于这一点,文末会说到,大家持续浏览)......文末会提供残缺代码,供大家更好的了解 应用express创立一个十万条数据的接口若是道友对express相干不太熟悉的话,有空能够看看笔者的这一篇全栈文章(还有残缺代码哦):《Vue+Express+Mysql全栈我的项目之增删改查、分页排序导出表格性能》route.get("/bigData", (req, res) => { res.header('Access-Control-Allow-Origin', '*'); // 容许跨域 let arr = [] // 定义数组,寄存十万条数据 for (let i = 0; i < 100000; i++) { // 循环增加十万条数据 arr.push({ id: i + 1, name: '名字' + (i + 1), value: i + 1, }) } res.send({ code: 0, msg: '胜利', data: arr }) // 将十万条数据返回之})点击按钮,发申请,获取数据,渲染到表格上html构造如下: <el-button :loading="loading" @click="plan">点击申请加载</el-button><el-table :data="arr"> <el-table-column type="index" label="序" /> <el-table-column prop="id" label="ID" /> <el-table-column prop="name" label="名字" /> <el-table-column prop="value" label="对应值" /></el-table>data() { return { arr: [], loading: false, };},async plan() { // 发申请,拿数据,赋值给arr}计划一 间接渲染所有数据如果申请到10万条数据间接渲染,页面会卡死的,很显然,这种形式是不可取的 ...

February 28, 2023 · 5 min · jiezi

关于性能优化:DMotion-基于DOTS的动画框架和状态机

【博物纳新】专栏是UWA旨在为开发者举荐新鲜、易用、乏味的开源我的项目,帮忙大家在我的项目研发之余发现世界上的热门我的项目、前沿技术或者令人惊叹的视觉效果,并摸索将其利用到本人我的项目的可行性。很多时候,咱们并不知道本人想要什么,直到某一天咱们遇到了它。 明天举荐的我的项目来自UWA开源库:https://lab.uwa4d.com/Lab/62b... 一、简介自从Unity推出了DOTS(Data-Oriented Technology Stack,面向数据的技术堆栈)之后,对于其利用始终备受关注。尽管DOTS对性能的晋升比拟显著,然而因为其不算低的门槛,依然让许多开发者难以上手。以动画为例,截至目前的Entities 1.0版本依然没有官网的基于Entities的动画解决方案。本文介绍的插件DMotion就提供了基于DOTS的动画框架和状态机,能够帮忙开发者更便捷地应用DOTS制作动画。 二、性能概览DMotion的根底是另一个开源我的项目Latios-Framework的Kinemation局部。这个我的项目应用DOTS建设了一些罕用模块的框架,包含物理、音频、动画等等,目前仍在频繁更新中,对于心愿学习和应用DOTS的开发者也能够作为参考,链接如下:https://lab.uwa4d.com/Lab/5df... 因为Latios-Framework应用了另一种动画压缩计划,即应用了插件Animation Compression Library,这个插件尽管实践上能够用于挪动端,然而目前还没有进行相应的适配,因而DMotion目前只能在PC平台上应用。作者提到之后会思考扩大到挪动端上。 目前DMotion的次要性能如下:Current Features (V0.3.4): Fully Bursted RuntimeState Machine Visual EditorTransitions: Boolean, Int, Enum And End TimeSimple API For Playing Clips Through Code (See Samples)1D Blend TreeAnimation EventsRoot Motion (With Writegroup Support, If You Need To Override Default Behaviour)Object AttachmentSupport For Optimized And Non-Optimized SkeletonsState Machine Visual Debugging之后可能会更新的性能:Planned Features: 2D Blend Tree (Cartesian/Freeform)State Machine Override (A.K.A Animator Override Controller)SubstatesIK SupportMultiple LayersSkeleton Masks三、应用Latios-Framework最新的版本(目前为0.6.4)曾经反对Entities 1.0,然而DMotion还只反对Entities 0.51版本,因而装置DMotion的Package之后须要装置Latios-Framework的旧版本,倡议应用0.5.8版本。 ...

February 24, 2023 · 1 min · jiezi

关于性能优化:手写一个业务数据比对库

在开发 web 应用程序时,性能都是必不可少的话题。同时通用 web 应用程序离不开数据的增删改查,尽管用户大部分操作都是在查问,然而咱们也不能够疏忽更改数据对于零碎的影响。于是集体写了一个业务数据比对库 diff-helper。不便开发者在前端提交数据到服务端时候去除不必要的信息,优化网络传输和服务端性能。 我的项目演进任何我的项目都不是一触而就的,上面是对于 diff-helper 库的编写思路。心愿能对大家有一些帮忙。 简略对象比对前端提交 JSON 对象数据时,很多状况下都是对象一层数据比对。在不思考对象中还有简单数据(嵌套对象和数组)的状况下,编写如下代码 // newVal 示意新数据,oldVal 示意老数据const simpleObjDiff = ({ newVal, oldVal,}): Record<string, any> => { // 以后比对的后果 const diffResult: Record<string, any> = {}; // 曾经查看过的数据项,能够优化遍历性能 const checkedKeys: Set<string> = new Set(); // 遍历最新的对象属性 Object.keys(newVal).forEach((key: string) => { // 将新数据的 key 记录一下 checkedKeys.add(key); // 如果以后新的数据不等于老数据,间接把新的比对后果放入 if (newVal[key] !== oldVal[key]) { diffResult[key] = newVal[key]; } }); // 遍历之前的对象属性 Object.keys(oldVal).forEach((key) => { // 如果曾经查看过了,不在进行解决 if (checkedKeys.has(key)) { return; } // 新的数据有,然而老数据没有能够认为数据曾经不存在了 diffResult[key] = null; }); return diffResult;};此时咱们就能够应用该函数进行一系列简略数据操作了。 ...

December 1, 2022 · 7 min · jiezi

关于性能优化:浅谈App的启动优化

1. 利用启动的形式在Android中,利用启动个别可分为三种:冷启动、温启动、热启动。 那么什么是冷启动、温启动和热启动呢?上面咱们来简略看一下它们的定义: 冷启动:当启动利用时,后盾没有该利用的过程。这时零碎会又一次创立一个新的过程调配给该利用,这个启动形式就是冷启动。温启动:当启动利用时,后盾已有该利用的过程,然而Activity可能因为内存不足被回收。这样零碎会从已有的过程中来启动这个Activity,这个启动形式叫温启动。热启动:当启动利用时,后盾已有该利用的过程,且Activity依然存在内存中没有被回收。这样零碎间接把这个Activity拉到前台即可,这个启动形式叫热启动。因为冷启动绝对于其余启动形式多了过程的创立(Zygote过程fork创立过程)以及利用的资源加载和初始化(Application的创立及初始化),所以相对来说会比拟耗时,所以咱们个别说的App启动优化个别指的都是App的冷启动优化。 2. 优化计划App启动优化的实质就是:启动速度和体验的优化。 这就好比早些年你去饭店吃饭,你想要点餐但等了半天都没有服务人员过去,可能就等得不耐烦间接走开了。同样的,对于APP来说,如果用户点击App后长时间都打不开,用户就很可能失去急躁而卸载利用。 所以启动速度是用户对咱们App的第一体验。如果启动速度过慢,用户第一印象就会很差,这样即便你性能做出花来,用户也不会违心去应用。 其实要想优化App的启动体验,要害就是要让用户更快地获取到利用的内容(晦涩,不卡顿、不期待),那么咱们应该怎么做呢? 2.1 案例剖析这里咱们还是先以之前说的去饭店吃饭为例来展开讨论。当初的饭店竞争是尤为得强烈,为了可能进步顾客的体验、留住顾客,真的是使出了浑身解数,除了口味之外,服务品质也是被摆在了越来越重要的地位。 就比方说: 为了可能更快地给用户提供点餐服务,当初的饭店每个座子上根本都贴上了点餐的二维码。一些热门须要排队的餐馆,在前台张贴了二维码,提供排队取号和提前点餐服务。一些长年爆满须要排队的餐馆,还提供了零食、茶水、棋牌以及美甲等服务。有些餐厅为了进步上菜的速度和体验,设置了倒计时免单的服务。以上的改良措施,都是这些年餐饮行业在竞争下,一直进步服务质量的产物。能够说谁的服务质量落下了,谁就有可能被淘汰。 其实咱们仔细分析一下下面所列举的,不难看出有很多是能够让咱们借鉴的。 (1)案例1 剖析:饭店提供了点餐的二维码,实质上是将一件被动期待转变为被动申请的一种过程,主观上缩小了期待的工夫,从而进步了速度。 类比:这对应咱们的应用程序,就像原先一些耗时不必要的三方库须要被动期待其初始化结束程序才会持续进行,转变为先不初始化这部分耗时的三方库,等真正用到时再进行初始化;又相似咱们应用程序的游客模式,无需被迫进行一堆简单的用户注册过程,就能够间接进入程序应用,待波及一些用户信息性能的时候再提醒用户注册。 (2)案例2 剖析:热门餐馆同时提供排队取号和提前点餐服务,实质上是将原先无奈同时进行的操作(须要先排上队等到座位,能力扫描座位号点餐)变成了可同时进行的操作,将串行工作转化为并行任务,从而节俭了工夫。 类比:这对应咱们的应用程序,就是将一些本来在主线程串行执行的耗时资源/数据加载,改为在子线程中并发执行。这在几个耗时工作耗时差距不大的时候优化尤为显著。 (3)案例3 剖析:在顾客排队期待的时候,提供零食、茶水、棋牌以及美甲等服务,实质上就是让顾客提前享受本餐馆的服务,从而缓解顾客期待的焦虑。 类比:这对应咱们的应用程序,就是开屏启动页。在Android12上,Google强制减少了这个开屏页,就是为了让用户提前看到你的利用页面,让用户产生利用启动很晦涩的假象,从而进步用户的启动体验。 (4)案例4 剖析:设置倒计时免单服务,实质上就是给期待加上了进度条下限以及超时抵偿。俗话说最让人胆怯的是期待,比期待更让人胆怯的是看不见止境的期待。而为期待设置下限,能够极大地缓解顾客期待的焦虑,毕竟期待超时了也是会有弥补的。 类比:这对应咱们的应用程序,就是一些利用(比方游戏)首次启动会十分耗时,所以它们通常会在启动页减少一个初始化/加载进度条页面,来通知用户啥时候能加载完,而不是无止境未知的期待。 通过剖析,咱们能够看到(1)、(2)两种操作是从技术的角度来实现的优化,而(3)、(4)两种操作则更多的是从业务的角度去实现的优化。 2.2 优化策略从下面的案例剖析,咱们能够得出,利用启动优化,咱们能够别离从技术和业务的角度来进行决策。 2.2.1 技术优化(1)针对启动流程工作进行梳理。 无耗时工作 -> 主线程耗时且须要同步工作 -> 异步线程 + 同步锁耗时且无需同步工作 -> 异步线程(2)非必要不执行。 非必要数据 -> 懒加载非必要工作 -> 提早/闲暇执行非必要界面/布局 -> 提早加载非必要性能 -> 删除/插件化(3)数据结构优化,减小初始化工夫。 数据结构尽可能复用,防止内存抖动数据结构申请的空间要恰到好处,不能过大(占用空间,创立慢)也不能过小(频繁裁减,效率低)对于必要且量大的数据,可采取分段加载。重要的资源本地缓存2.2.2 业务优化(1)业务流程整合。 多个相干的串行业务整合为对立的一个业务。不相干的串行业务整合为并行的业务。(2)业务流程拆分调整。 对业务进行拆分,拆分出次要(必要)业务和主要(非必要)业务。别离对次要业务和主要业务进行优先级评估,业务执行按优先级从高到底顺次执行。2.3 优化方向在优化之前,让咱们先来剖析一下冷启动的过程: Zygote创立利用过程 -> AMS申请ApplicationThread -> Application创立 -> attachBaseContext > onCreate -> ActivityThread启动Activity -> Activity生命周期(创立、布局加载、屏幕安排、首帧绘制)以上过程,只有Application和Activity的生命周期这两个阶段对咱们来说是可控的,所以这就是咱们的优化方向。 3. 优化措施3.1 启动流程优化1.根据之前咱们列举的技术优化策略,首先须要对启动的所有工作流程进行梳理,而后对其执行形式进行优化。 ...

November 21, 2022 · 2 min · jiezi

关于性能优化:前端性能优化掌握行业实用专业前沿的解决方案

download:前端性能优化,把握行业实用、业余、前沿的解决方案StampedLock读写锁“StampedLock简介”StampedLock的状态由版本和模式组成。get lock办法返回一个示意和管制对锁状态的拜访的戳。StampedLock提供三种模式来管制拜访锁: 写入模式 获取写锁,这是独占的。当锁处于写模式时,您无奈取得读锁,并且所有乐观读验证都将失败。 writeLock():阻塞期待锁的独占获取,并返回一个戳。如果为0,则采集失败。TryWriteLock():`尝试获取一个写锁并返回一个工夫戳。如果为0,则采集失败。Long trywritelock (长时间,工夫单位单位):当试图获取一个独占写锁时,能够期待一个事件并返回一个stamp。如果为0,则采集失败。 long writelockinterrupt():尝试获取一个独占的写锁,它能够被中断并返回一个工夫戳。如果为0,则采集失败。UnlockWrite(long stamp):`开释独占写锁,并传入以前获取的stamp。 tryUnlockWrite():如果持有写锁,则该锁将在没有标记值的状况下被开释。这种办法对于出错后的复原可能很有用。 long stamp = lock . write lock();尝试{....}最初{lock.unlockWrite(戳);}复制代码 读取模式 独占读锁之后的乐观之路。 readLock():阻塞期待获取非独占读锁,并返回一个stamp。如果为0,则采集失败。TryReadLock():`尝试获取一个读锁并返回一个工夫戳。如果为0,则采集失败。长读锁(long time,工夫单位单位):当试图获取读锁时,能够期待一个事件并返回一个工夫戳。如果为0,则采集失败。Readlockinterrupt():期待获取非独占读锁的块,它能够被中断并返回一个stamp。如果为0,则采集失败。UnlockRead(long stamp):开释非独占读锁,并传入之前获取的stamp。 tryUnlockRead():如果持有读锁,开释持有一次,不须要stamp值。这种办法对于出错后的复原可能很有用。 长戳= lock . read lock();尝试{....}最初{lock . unlock read(stamp);}复制代码 乐观浏览模式 乐观是指如果读操作多,写操作少,能够乐观地认为写和读同时产生的概率很小,能够应用齐全读锁,不乐观。在读取数据后,程序能够通过写入来查看它是否被更改,而后采取后续措施(从新读取更改的信息或抛出异样)。这个小小的改良能够大大提高程序的吞吐量。StampedLock反对tryOptimisticRead()办法。浏览后,进行盖章查看。如果查看通过,则意味着在此期间没有其余线程写入,数据能够平安应用。如果查看失败,须要从新获取读锁以确保数据一致性。 TryOptimisticRead():`返回一个能够在当前验证的戳,如果以独占形式锁定,则返回零。 boolean validate(long stamp):如果自给定的stamp收回后锁尚未被独占获取,则返回true。 long stamp = lock . trypositicread();//查看戳记如果(!lock.validate(stamp)){//锁定降级}复制代码此外,StampedLock提供api来实现上述三种转换形式: `长tryConvertToWriteLock(长戳)' 如果锁定状态与给定的标记匹配,请执行下列操作之一。如果该标记批示持有写锁,则返回该标记。或者,如果是读锁,并且写锁可用,则开释读锁并返回写戳。或者,在乐观读取的状况下,写戳只有在立刻可用时才返回。在所有其余状况下,该办法返回零。 ` long tryConvertToReadLock(长戳)' 如果锁定状态与给定的标记匹配,请执行下列操作之一。如果标记批示持有写锁,则开释它并取得读锁。或者,如果是读锁,则返回它。或者,在乐观读取的状况下,只有当读取标记立刻可用时,才会取得读取锁并返回读取标记。在所有其余状况下,该办法返回零。 长tryConvertToOptimisticRead(长戳)如果锁的状态与给定的标记相匹配,那么如果标记批示锁被持有,则开释锁并返回察看标记。或者,如果是乐观浏览,验证后返回。在所有其余状况下,该办法都返回0,因而它作为“tryUnlock”的一种模式可能很有用。演示示例用上面的例子来演示StampedLock的用法。这个例子来自jdk中的javadoc。 @Slf4j@数据公共类点{公有双x,y;private final StampedLock sl = new StampedLock();void move(double deltaX,double deltaY)抛出中断异样{//波及共享资源的批改,应用写锁排他操作。long stamp = sl . write lock();log.info("writeLock锁胜利");thread . sleep(500);尝试{x+= deltaX;y+= deltaY;}最初{sl.unlockWrite(盖章);log.info("解锁写锁胜利");}}/***应用乐观读锁访问共享资源。*留神:乐观读锁须要将一个要操作的变量复制到办法栈中,以保证数据的一致性,其余写者在操作数据时可能曾经批改了数据。*而咱们操作的是办法栈中的数据,也就是快照,所以返回最多的数据不是最新的数据,然而一致性还是有保障的。** @返回*/double distanceFromOrigin()抛出InterruptedException {long stamp = sl . trypositicread();//应用乐观读锁log . info(" trypositicread锁胜利");//睡一秒钟thread . sleep(1000);double currentX = x,currentY = y;//将共享资源复制到本地办法堆栈中。如果(!Sl.validate(stamp)) {//如果写锁被占用,可能会导致数据不统一,所以切换到失常的读锁模式。log.info("验证戳记谬误");stamp = sl . read lock();log.info("readLock胜利");尝试{currentX = x;currentY = y;}最初{sl.unlockRead(盖章);log.info("解锁读取胜利");}}return math . sqrt(currentX * currentX+currentY * currentY);}void moveIfAtOrigin(double newX,double newY) { //降级//能够从乐观模式而不是读取模式开始长戳= sl . read lock();尝试{while (x == 0.0 && y == 0.0) {long ws = sl . tryconverttowritelock(stamp);//读锁转换为写锁如果(ws!= 0L) {stamp = wsx = newXy = newY突破;}否则{sl.unlockRead(盖章);stamp = sl . write lock();}}}最初{sl.unlock(盖章);}}}复制代码 ...

October 19, 2022 · 2 min · jiezi

关于性能优化:产品好不好谁说了算Sonar提出分析的性能指标帮助您轻松判断产品性能及表现

近日,Sonar产品经理发表了Sonar全新的、明确的剖析性能指标,以更好地与其余有雷同指标或后果的工具进行比拟。作为SonarQube受权合作伙伴,创实继续关注代码平安畛域,为中国用户带来寰球范畴内的优良工具和解决方案,帮忙企业实现开发经营平安一体化。在本文中,Sonar产品经理Alexandre Gigleux具体解读了Sonar最新提出的性能指标、目前的指标实现进度,以及接下来的首要任务。 在此,我很骄傲地发表Sonar性能剖析指标。始终以来,当用户探讨到Sonar剖析性能时,会分为两种状况: 挑战:用户一直尝试冲破极限,报告他们认为应改良的问题案例。称心:因为用户已对要运行数小时且总是产生大量误报后果的SAST工具司空见惯,他们对Sonar感到称心。但无论是面对以上何种状况,咱们都不晓得该如何应答。因为最后咱们在开始构建剖析引擎时,脑海中没有明确的性能指标。方向尚不明确,是否达到指标这一命题就不成立。因而,在您告知咱们性能还不够好的时候,咱们并不分明您的这些倡议是否可取。这就是为什么咱们最终决定须要建设明确的性能剖析指标:这样咱们就不会将本人的产品与其它可能没有雷同指标或后果的工具进行简略的比拟,也不会主观地、从集体角度去评估剖析“看起来”怎么样。当初,咱们能够明确地告知您能够从咱们的产品中取得些什么,以及在标准化的条件下,剖析我的项目所须要的工夫。那么,就让咱们看看这些指标是什么,以及这些指标的实现状况。 第一次剖析须要多长时间?第一次剖析应该了解为对一个分支的所有文件进行剖析。当您在SonarQube或SonarCloud中退出新我的项目时,以及创立新分支时,这种状况都会产生。在这种状况下,您能够期待在不到几分钟的工夫内就能看到我的项目的总体状态,具体几分钟则取决于我的项目规模: 依据在SonarCloud上的测量后果,咱们的产品在解决M、L和XL类我的项目时都达标了——这些我的项目中的95%是在指标工夫范畴内实现剖析的。因为开始分析阶段的工夫耗费,XS和S类我的项目尚未达到要求。 代码变更剖析须要多长时间?代码变更剖析产生通常在以下两种状况下产生: 创立一个pull request后,心愿在合并前验证PR品质。间接将文件提交到分支(主分支或其它分支),而未应用pull/merge request机制。在这种情景下,咱们天然地冀望剖析工夫与变更汇合的规模(增加或更新代码的数量)成正比,而不是像第一次剖析那样须要期待雷同的工夫。在这里,您能够期待在几分钟内看到您的我的项目、分支或PR更新后的品质关口(Quality Gate,也译作品质门),具体须要花几分钟则取决于代码更改的规模: 到目前为止,咱们为实现这些指标做了哪些工作?咱们的新定义:一个我的项目能够蕴含多种编程语言。咱们以我的项目中代码密度最大的语言来给我的项目命名,这让将一个特定的我的项目形容为Java、TypeScript或PHP我的项目变得很不便。 第一次剖析执行工夫 就Java目而言,咱们对其总体剖析性能进行了改良。与SonarQube 9.3相比,SonarQube 9.4的Java剖析速度均匀提速30%。一位测试了该版本的客户示意,他可能在不到18分钟的工夫内剖析一个1M LOC我的项目。这齐全达到了咱们的指标(<40分钟),表明咱们的产品已达到了良好的剖析成果。 对于Kotlin我的项目,咱们将剖析性能进步了10倍,达到了性能指标。就C/C++我的项目而言,从SonarQube 9.5开始,咱们默认的剖析是多线程的。在这之前,它是一个可选选项,最新版本中咱们将其改成了默认选项。通过此变动,剖析中会调配到更多的CPU,从而更容易达到预期的指标。 代码变更剖析执行工夫 对于Sonar所笼罩的许多语言,咱们不须要从所有文件中收集信息来进步后果品质,这种状况下,只须要剖析pull request波及到的文件。从2022年5月3日起,这一性能能够从SonarQube 9.3和SonarCloud上取得。如果pull request中蕴含CSS、HTML、XML、Ruby、Scala、Go、Apex、CloudFormation、Terraform、Swift、PL/SQL、T-SQL、ABAP、VB6、Flex和RPG等代码的变更,则pull request的剖析效率通常会失去一些改善。 对于主体是Java代码的pull request,因为咱们不再须要对整个我的项目级的数据进行剖析,而只针对更改文件执行剖析,所以速度还会再晋升8-25%。总的来说晋升了,然而咱们还未达到咱们代码变更剖析时长的指标。 接下来,咱们要做什么?作为咱们的首要任务,咱们心愿优化Java我的项目的pull request剖析工夫。咱们将借助存储我的项目级数据的新缓存机制实现这一点,这将确保咱们的剖析后果领有较高的准确性。为什么首先优化Java?因为Java是Sonar反对的第一种语言,也是被咱们用户应用最多的一种语言。此外,Sonar的开发人员应用了大量Java,因而咱们可能在公布前轻松发现问题。 接下来,咱们将借助同一缓存系统优化分支的代码更改剖析。 当运行稳固后,咱们会将其扩大到JS/TS、PHP、Python和COBOL等语言。 想要体验 SonarQube或试用SonarCloud,请分割SonarQube中国官网受权合作伙伴——创实 ,咱们提供SonarQube产品的征询、销售、 施行、培训及技术支持服务。 作者简介: ALEXANDRE GIGLEUX 产品经理 文章起源:https://blog.sonarsource.com/...

July 4, 2022 · 1 min · jiezi

关于性能优化:TiDB-性能分析amp性能调优amp优化实践大全

本文蕴含: TiDB 性能优化概述TiDB 性能剖析和优化OLTP 负载性能优化实际Performance Overview 面板重要监控指标详解1、TiDB 性能优化概述https://tidb.net/blog/1731b977 2、TiDB 性能剖析和优化本文介绍了基于数据库工夫的系统优化办法,以及如何利用 TiDB Performance Overview 面板进行性能剖析和优化。 通过本文中介绍的办法,你能够从全局、自顶向下的角度剖析用户响应工夫和数据库工夫,确认用户响应工夫的瓶颈是否在数据库中。如果瓶颈在数据库中,你能够通过数据库工夫概览和 SQL 提早的合成,定位数据库外部的瓶颈点,并进行针对性的优化。 基于数据库工夫的性能优化办法TiDB 对 SQL 的解决门路和数据库工夫进行了欠缺的测量和记录,不便定位数据库的性能瓶颈。即便在用户响应工夫的性能数据缺失的状况下,基于 TiDB 数据库工夫的相干性能指标,你也能够达到以下两个性能剖析指标: 通过比照 SQL 解决均匀提早和事务中 TiDB 连贯的闲暇工夫,确定整个零碎的瓶颈是否在 TiDB 中。如果瓶颈在 TiDB 外部,依据数据库工夫概览、色彩优化法、要害指标和资源利用率、自上而下的提早合成,定位到性能瓶颈具体在整个分布式系统的哪个模块。确定整个零碎的瓶颈是否在 TiDB 中如果事务中 TiDB 连贯的均匀闲暇工夫比 SQL 均匀解决提早高,阐明利用的事务处理中,次要的提早不在数据库中,数据库工夫占用户响应工夫比例小,能够确认瓶颈不在数据库中。在这种状况下,须要关注数据库内部的组件,比方应用服务器硬件资源是否存在瓶颈,利用到数据库的网络提早是否过低等。如果 SQL 均匀解决提早比事务中 TiDB 连贯的均匀闲暇工夫高,阐明事务中次要的瓶颈在 TiDB 外部,数据库工夫占用户响应工夫比例大。如果瓶颈在 TiDB 外部,如何定位一个典型的 SQL 的解决流程如下所示,TiDB 的性能指标笼罩了绝大部分的解决门路,对数据库工夫进行不同维度的合成和上色,用户能够疾速的理解负载个性和数据库外部的瓶颈。 数据库工夫是所有 SQL 解决工夫的总和。通过以下三个维度对数据库工夫进行合成,能够帮忙你疾速定位 TiDB 外部瓶颈: 按 SQL 解决类型合成,判断哪种类型的 SQL 语句耗费数据库工夫最多。对应的合成公式为: DB Time = Select Time + Insert Time + Update Time + Delete Time + Commit Time + ...按 SQL 解决的 4 个步骤(即 get_token/parse/compile/execute)合成,判断哪个步骤耗费的工夫最多。对应的合成公式为: DB Time = Get Token Time + Parse Time + Comiple Time + Execute Time对于 execute 耗时,依照 TiDB 执行器自身的工夫、TSO 等待时间、KV 申请工夫和重试的执行工夫,判断执行阶段的瓶颈。对应的合成公式为: Execute Time ~= TiDB Executor Time + KV Request Time + PD TSO Wait Time + Retried execution time利用 Performance Overview 面板进行性能剖析和优化本章介绍如何利用 Grafana 中的 Performance Overview 面板进行基于数据库工夫的性能剖析和优化。 ...

June 20, 2022 · 9 min · jiezi

关于性能优化:性能调优监控软件应该注意哪些要点一般性能测试调优的步骤Alltesting泽众云测试

性能测试调优应该留神的要点: 要点1:在利用零碎的设计开发过程中,应始终把性能放在思考的范畴内。 要点2:确定清晰明确的性能指标是要害。 要点3:必须保障调优后的程序运行正确。 要点4:零碎的性能更大程度上取决于良好的设计,调优技巧只是一个辅助伎俩。 要点5:调优过程是迭代渐进的过程,每一次调优的后果都要反馈到后续的代码开发中去。 要点6:性能调优不能以就义代码的可读性和可维护性为代码。 个别性能测试调优的步骤: 步骤一:确定问题 步骤二:剖析问题 步骤三:确定调整指标和解决方案 步骤四:性能测试解决方案 步骤五:剖析性能调优后果 最初,如果达到了预期指标,性能调优工作就根本能够完结了。 举荐浏览:在线性能测试服务性能测试软件有哪些软件性能测试机构有哪些功能测试包含哪些方面测试 相干工具:PerformanceRunner性能测试工具性能监控软件APMAPM性能监控软件工具在线性能测试工具

June 16, 2022 · 1 min · jiezi

关于性能优化:以一次Data-Catalog架构升级为例聊业务系统的性能优化

摘要字节的 DataCatalog 零碎,在 2021 年进行过大规模重构,新版本的存储层基于 Apache Atlas 实现。迁徙过程中,咱们遇到了比拟多的性能问题。本文以 Data Catalog 系统升级过程为例,与大家探讨业务零碎性能优化方面的思考,也会介绍咱们对于 Apache Atlas 相干的性能优化。 背景字节跳动 Data Catalog 产品晚期,是基于 LinkedIn Wherehows 进行二次革新,产品晚期只反对 Hive 一种数据源。后续为了反对业务倒退,做了很多修修补补的工作,零碎的可维护性和扩展性变得不可忍耐。比方为了反对数据血统能力,引入了字节外部的图数据库 veGraph,写入时,须要业务层解决 MySQL、ElasticSearch 和 veGraph 三种存储,模型也须要同时了解关系型和图两种。更多的背景能够参照之前的文章。 新版本保留了原有版本全量的产品能力,将存储层替换成了 Apache Atlas。然而,当咱们把存量数据导入到新零碎时,许多接口的读写性能都有重大降落,服务器资源的应用也被拉伸到夸大的境地,比方: 写入一张超过 3000 列的 Hive 表元数据时,会继续将服务节点的 CPU 占用率晋升到 100%,十几分钟后触发超时一张几十列的埋点表,上下游很多,关上详情展现时须要等 1 分钟以上为此,咱们进行了一系列的性能调优,联合 Data Catlog 产品的特点,调整了 Apache Atlas 以及底层 Janusgraph 的实现或配置,并对优化性能的方法论做了一些总结。业务系统优化的整体思路在开始探讨更多细节之前,先概要介绍下咱们做业务类系统优化的思路。本文中的业务零碎,是绝对于引擎零碎的概念,特指解决某些业务场景,给用户间接裸露前端应用的 Web 类零碎。 优化之前,首先应明确优化指标。与引擎类零碎不同,业务类零碎不会谋求极致的性能体验,更多是以解决理论的业务场景和问题登程,做针对性的调优,须要分外留神防止过早优化与适度优化。 精确定位到瓶颈,能力事倍功半。一套业务零碎中,能够优化的点通常有很多,从业务流程梳理到底层组件的性能晋升,然而对瓶颈处优化,才是 ROI 最高的。 依据问题类型,挑性价比最高的解决方案。解决一个问题,通常会有很多种不同的计划,就像条条大路通罗马,但在理论工作中,咱们通常不会谋求最完满的计划,而是选用性价比最高的。 优化的成果得能疾速失去验证。性能调优具备肯定的不确定性,当咱们做了某种优化策略后,通常不能上线察看成果,须要一种更麻利的验证形式,能力确保及时发现策略的有效性,并及时做相应的调整。 业务系统优化的细节优化指标的确定在业务零碎中做优化时,比拟禁忌两件事件: 过早优化:在一些性能、实现、依赖零碎、部署环境还没有稳固时,过早的投入优化代码或者设计,在后续零碎产生变更时,可能会造成精力节约。适度优化:与引擎类零碎不同,业务零碎通常不须要跑分或者与其余零碎产出性能比照报表,理论工作中更多的是贴合业务场景做优化。比方用户间接拜访前端界面的零碎,通常不须要将响应工夫优化到 ms 以下,几十毫秒和几百毫秒,曾经是满足要求的了。 优化范畴抉择对于一个业务类 Web 服务来说,特地是重构阶段,优化范畴比拟容易圈定,次要是找出与之前零碎相比,显著变慢的那局部 API,比方能够通过以下形式收集须要优化的局部: 通过前端的慢查问捕获工具或者后端的监控零碎,筛选出 P90 大于 2s 的 API页面测试过程中,研发和测试同学陆续反馈的 API数据导入过程中,研发发现的写入慢的 API 等 ...

June 8, 2022 · 2 min · jiezi

关于性能优化:2022-前端性能优化最佳实践

背景随着业务的一直迭代,我的项目日渐壮大,为了给用户提供更优的体验,性能优化是前端开发避不开的话题。一个优良的网站必然是领有丰盛性能的同时具备比拟块的响应速度,想必咱们浏览网页时都更喜爱丝般顺滑的感触。 最近在学习整顿前端性能优化方面的常识,看了很多的文章,感觉文章多了比拟零散,学习效率不高,所以在浏览和学习其余优良博客文章的同时本人做了整顿和演绎,与大家一起学习和共勉。 本文相干图文内容多来自于稀土掘金社区,援用参考文献出处均在文章开端显著标注。 如有侵权,分割删除 一、性能优化的实质性能优化的目标,就是为了提供给用户更好的体验,这些体验蕴含这几个方面:展现更快、交互响应快、页面无卡顿状况。 更具体的说,就是指,在用户输出url到站点残缺把整个页面展现进去的过程中,通过各种优化策略和办法,让页面加载更快;在用户应用过程中,让用户的操作响应更及时,有更好的用户体验。 对于前端工程师来说,要做好性能优化,须要了解浏览器加载和渲染的实质。了解了实质原理,能力更好的去做优化。 二、雅虎性能优化军规雅虎军规是雅虎的开发人员在总结了网站的不合理局部后,提出的优化网站性能进步的一套办法规定,非常适合初学者绕过这些坎。十分简要,供大家参考应用,心愿对你们当前的开发过程中有所帮忙。 三、性能优化指标3.1 以用户为核心的性能指标First Paint 首次绘制(FP)这个指标用于记录页面第一次绘制像素的工夫,如显示页面背景色。 FP不蕴含默认背景绘制,但蕴含非默认的背景绘制。First contentful paint 首次内容绘制 (FCP)LCP是指页面开始加载到最大文本块内容或图片显示在页面中的工夫。如果 FP 及 FCP 两指标在 2 秒内实现的话咱们的页面就算体验优良。Largest contentful paint 最大内容绘制 (LCP)用于记录视窗内最大的元素绘制的工夫,该工夫会随着页面渲染变动而变动,因为页面中的最大元素在渲染过程中可能会产生扭转,另外该指标会在用户第一次交互后进行记录。官网举荐的工夫区间,在 2.5 秒内示意体验优良First input delay 首次输出提早 (FID)首次输出提早,FID(First Input Delay),记录在 FCP 和 TTI 之间用户首次与页面交互时响应的提早。Time to Interactive 可交互工夫 (TTI)首次可交互工夫,TTI(Time to Interactive)。这个指标计算过程稍微简单,它须要满足以下几个条件: 从 FCP 指标后开始计算继续 5 秒内无长工作(执行工夫超过 50 ms)且无两个以上正在进行中的 GET 申请往前回溯至 5 秒前的最初一个长工作完结的工夫对于用户交互(比方点击事件),举荐的响应工夫是 100ms 以内。那么为了达成这个指标,举荐在闲暇工夫里执行工作不超过 50ms( W3C 也有这样的标准规定),这样能在用户无感知的状况下响应用户的交互,否则就会造成提早感。 Total blocking time 总阻塞工夫 (TBT)阻塞总工夫,TBT(Total Blocking Time),记录在 FCP 到 TTI 之间所有长工作的阻塞工夫总和。Cumulative layout shift 累积布局偏移 (CLS)累计位移偏移,CLS(Cumulative Layout Shift),记录了页面上非预期的位移稳定。页面渲染过程中忽然插入一张微小的图片或者说点击了某个按钮忽然动静插入了一块内容等等相当影响用户体验的网站。这个指标就是为这种状况而生的,计算形式为:位移影响的面积 * 位移间隔。3.2 三大外围指标(Core Web Vitals)Google 在20年五月提出了网站用户体验的三大外围指标 ...

April 24, 2022 · 8 min · jiezi

关于性能优化:前端性能如何体系化HeapDump性能社区和前端早早聊深度深度合作探索答案

数字化时代和性能随着数字化时代的到来,咱们的生存开始逐步被各种利用所突围。对于各种利用,咱们也从最后的能用就行,到当初有了各种各样的体验谋求。而一个利用体验好不好,性能就是其中最要害的指标。 那什么是利用性能呢?由谁来负责利用的性能指标呢?其实性能波及方方面面,从产品设计到需要开发,从测试上线到公布后运维,每一个环节都和性能相干,也就是意味着每一个技术从业者在工作中都要面临性能相干的问题。 在这个趋势下,HeapDump性能社区呈现了,它是笨马网络旗下国内首个垂直于性能畛域的开发者社区,致力于帮忙更多开发者们理解性能调优,诊断性能问题,从而能给用户提供更好的应用服务。 测试开发者在这里能够理解到性能测试相干的常识和案例,不同畛域的开发人员也能够在这里找到各种和性能相干的源码剖析和思考,前端有前端性能,数据库也有数据库相干oom问题,Java虚拟机和中间件当然也不可或缺,最要害是这里有千百个性能案例,运维人员须要性能问题后茫然无助怎么办?这里就能找到类似的案例给你启发,甚至在问答区能够一键寻求专家帮助。 前端性能的重要性那么这么多性能问题里,哪些性能问题最要害么?你必定会说那当然是服务器宕机!没错,这个必定很重大,然而从用户体验感知上,服务器宕机产生的次数很少。对于用户来说,最直观的感触是一个页面关上快不快,页面酷炫不酷炫,按钮按的成果怎么样期待问题。 而这些问题,毫无疑问当然是前端性能问题。这也导致了前端利用性能成为了用户留存的必要条件之一。 作为国内最大的专一于性能畛域的垂直社区,HeapDump性能社区天然也把前端性能当作重点打造的内容,来帮忙更多开发者去理解前端性能,深刻并把握前端性能调优。这样开发者们能力去开发出体验更优良的利用和服务给用户。 业余的事件交给业余的人来做,业余的前端性能内容和服务,天然也须要交给业余的组织和机构。4月11日,HeapDump性能社区与国内前端出名社区前端早早聊通过屡次深刻沟通后,正式确定策略单干。 作为国内出名的专一前端畛域垂直社区,前端早早聊汇集了国内最优良的一批前端技术专家,也同样长期在第一线服务于前端开发者们的成长,所以既有丰盛的技术积攒,同样也有丰盛的开发者群体洞察。 此次单干,单方将集中各自劣势资源,意在打造一套长期的内容产品,去赋能更多前端开发者们成长,特地是前端性能畛域的成长。 单干的初心和瞻望对于单干的初心,HeapDump性能社区相干负责人花生示意,“现阶段,开发者们学习性能相干常识个别会去泛技术社区或综合学习型常识社区,然而这些中央都不够体系化,无奈像学校里学习一样,从易到难,一步一步去晋升。” “而HeapDump性能社区始终想要整合性能畛域相干内容和专家,一起去打造这么一整套体系化的常识,来帮忙开发者们更容易,更不便的入门性能,把握性能!” 对于这次单干,HeapDump性能社区通过这两年的经营,发现最有价值的体系化内容,仍然是把握在在那些最业余的专家和组织中,于是这次社区和前端早早聊接触并建设深度单干,就是为了一起独特打造一个由资深技术专家出品,简略易懂又体系化的前端性能内容产品,来帮忙开发者们成长。 前端早早聊的负责人Scott也示意:“前端性能问题被大多数人漠视了,作为和用户接触的桥头堡,将来将会越来越重要!刚好这也是一次契机,可能把前端性能问题体系化的整合起来,帮忙更多开发者去成长!”

April 22, 2022 · 1 min · jiezi

关于性能优化:性能优化-为虚拟列表增加离屏渲染和缓存

背景在之前的一篇对于有限滚动优化的文章中, 咱们应用了虚构列表来改善用户体验,并获得了不错的成果。 本篇是后续,在虚构列表中的图片缩略图减少离屏渲染和压缩缓存的能力, 作为性能加强。 次要的解决: 减少一个用离屏渲染压缩图片的 Avatar 组件, 并替换原有的 Avatar 组建;减少了 LRU Cache 来缓存压缩过后的图片;实验性的退出 Web worker 避免压缩图片时主线程卡顿;下文次要是分享具体方法的实现, 心愿对大家有所帮忙。 注释咱们晓得, 在虚构列表中, 视区之外的节点是不会被渲染的, 如图所示: 只有进入到视区, 或者设定的某个阈值, 比方高低一屏之内, 才会挂载和渲染, 以此来放弃总的结点数在一个正当的范畴内, 以此较少浏览器的累赘, 缩短屏幕响应工夫。 本地优化是针对列表中的图片, 做了一些解决, 来进步解决效率。 具体实现页面接入// viewimport AvatarWithZip from '../molecules/AvatarWithZip';- <Avatar className="product-image" src={record.image} size={32} />+ <AvatarWithZip className="product-image" src={record.image} size={32} openZip />组件实现// AvatarWithZipimport React, { useState } from 'react';import Avatar, { AvatarProps } from 'antd/lib/avatar';import useAvatarZipper from '@/hooks/use-avatar-zipper';interface PropTypes extends AvatarProps{ openZip: boolean;}const AvatarWithZip: React.FC<PropTypes> = (props) => { const { openZip, src, size, ...otherProps } = props; const [localSrc, setLocalSrc] = useState(openZip ? '' : src); const resize = useAvatarZipper(size as number); React.useEffect(() => { if (!openZip) { return; } if (typeof src === 'string') { resize(src).then(url => { setLocalSrc(url); }); } else if (typeof src === 'object') { setLocalSrc(src); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [src, openZip]); return ( <Avatar src={localSrc} size={size} {...otherProps} /> );};export default React.memo(AvatarWithZip);对应封装的 hooksimport React from 'react';import LRU from 'lru-cache';import AvatarZipWorker from '@/workers/avatar-zip.worker.ts';type UseAvatarZipper = (src: string) => Promise<string>;const MAX_IAMGE_SIZE = 1024;const zippedCache = new LRU<string, string>({ max: 500,});const worker = new AvatarZipWorker();const useAvatarZipper: (size?: number) => UseAvatarZipper = (size = 32) => { const offScreen = React.useRef<OffscreenCanvas>(new OffscreenCanvas(size, size)); const offScreenCtx = React.useRef(offScreen.current.getContext('2d')); React.useEffect(() => { offScreen.current = new OffscreenCanvas(size, size); offScreenCtx.current = offScreen.current.getContext('2d'); worker.postMessage({ type: 'init', payload: size }); }, [size]); const resize: (src: string, max?: number) => Promise<string> = React.useCallback((src, max = MAX_IAMGE_SIZE) => new Promise<string>((resolve, reject) => { const messageHandler = (event: MessageEvent) => { const { type, payload } = event.data; if (type === 'error') { reject(payload); } const { origin, dist } = payload; if (origin === src) { zippedCache.set(src, dist); resolve(dist); } }; if (zippedCache.has(src)) { resolve(zippedCache.get(src) as string); return () => {}; } worker.postMessage({ type: 'zip', payload: { src, max } }); worker.addEventListener('message', messageHandler); return () => { worker.removeEventListener('message', messageHandler); }; }), []); return resize;};export default useAvatarZipper;worker 实现const ctx: Worker = self as any;interface MessageData { type: string; payload: any;}export interface MessageReturnData { type: string; payload: any;}let offScreen: OffscreenCanvas;let offScreenCtx: OffscreenCanvasRenderingContext2D | null;// Respond to message from parent threadctx.addEventListener('message', async (event: MessageEvent<MessageData>) => { const { data } = event; const { type, payload } = data; if (type === 'init') { offScreen = new OffscreenCanvas(payload, payload); offScreenCtx = offScreen.getContext('2d'); } if (type === 'zip') { const { src, max } = payload; try { if (!offScreenCtx) { throw Error(); } const res = await fetch(src); const srcBlob = await res.blob(); const imageBitmap = await createImageBitmap(srcBlob); if (Math.max(imageBitmap.width, imageBitmap.height) <= max) { ctx.postMessage({ origin: src, dist: src, }); } const size = offScreen.width; offScreenCtx.clearRect(0, 0, size, size); offScreenCtx.drawImage(imageBitmap, 0, 0, size, size); const blobUrl = await offScreen.convertToBlob().then(blob => URL.createObjectURL(blob)); ctx.postMessage({ type: 'success', payload: { origin: src, dist: blobUrl, } }); } catch (err) { ctx.postMessage({ type: 'error', payload: err, }); } }});相干配置批改 // webpack 减少配置: { test: /\.worker\.ts$/, loader: 'worker-loader', options: { chunkFilename: '[id].[contenthash].worker.js', }, } // types declare module '*.worker.ts' { class WebpackWorker extends Worker { constructor(); } export default WebpackWorker; }总结总的来说, 实现思路并不简单, 次要是 worker 的实现,以及边界异样解决, 比方降级解决等。 ...

April 13, 2022 · 3 min · jiezi

关于性能优化:信通院牵头数列科技参与主编的信息系统稳定性保障能力建设指南正式发布

中国信息通信研究院分布式系统稳定性实验室正式公布了《信息系统稳定性保障能力建设指南》(下称《指南》)。数列科技应邀作为次要编写单位,深度参加了《指南》的编写制订;同时,数列提供稳定性保障服务的国家电网、浙江大学等,也被征集收录至零碎稳定性最佳实际案例中。 随着各畛域数字化转型的推动,用户的高频拜访成为常态,面对应用需要的一直增长,大多数信息系统通过分布式架构革新、DevOps 体系建设、大量引入开源技术来一直冲破本身解决能力下限,这些措施引入导致了信息系统架构复杂性呈指数回升,显著减少了稳定性危险。信息系统的稳定性影响着泛滥企业和用户的生产生存,同样也受到国家高度重视——2021年9月1日正式施行的《要害信息基础设施平安爱护条例》中对我国要害信息基础设施的稳定性保障工作提出了明确要求。 零碎稳定性是所有业务的基石,《指南》由此产生,它是国内首个全方位梳理总结稳定性保障相干实践经验、方法论的研究成果。《指南》梳理了新阶段下信息系统稳定性保障能力建设工作的相干背景、根本准则、要害因素、 外围能力以及评估体系,探讨了稳定性保障工作的将来发展趋势。指南开创性地提出了数字化时代下的信息系统稳定性保障体系,共蕴含“两个总体准则、三个要害因素、四类外围能力、五项重要工作”。(完整版指南可文末扫码关注【数列科技】回复“指南”获取) 本次《指南》公布,除了对系统稳定性的建设做了办法领导,同时兼顾各类稳定性需要,梳理了稳定性相干保障工具,进一步帮大家缩小工具选型上的工作。零碎稳定性问题在各行业多发,各单位也因背景和业务的差异性,抉择了不同解决形式,本次《指南》公布的信息系统稳定性最佳实际案例中,国家电网《网上国网零碎压测与演练工作》、浙江大学《学在浙大平台稳定性保障工作》等由数列提供服务的案例也被征集收录。 数列科技很荣幸受邀参加到《指南》的编写工作中,这是对数列在稳定性保障畛域业余能力的必定,也是对数列的踊跃鞭策,将来数列也将继续奋斗在零碎稳定性保障畛域一线,利用丰盛的保障实战经验帮忙更多企业搭建和欠缺本身的稳定性保障能力建设。扫码关注【数列科技】回复【指南】疾速获取完整版

April 2, 2022 · 1 min · jiezi

关于性能优化:NetCore-性能排查

@[toc] 一、性能排查性能的概念 性能的来源于零碎。 零碎分为两类:web零碎【BS】和客户端【桌面】零碎【CS】。 性能的指标依据 两个依据: 数量 客户端执行接口的数量,也就是1秒钟能执行多少个申请接口,解决的越多,性能越高。工夫 从客户端申请到服务端并响应申请产生的工夫称之为 性能工夫;工夫越短性能越高。 如图: 工夫和数量是一个矛盾关系:工夫越短执行的数量越多【吞吐量】,工夫越长执行的数量越少。 性能的终点在于执行一次接口的执行工夫。 获取零碎接口执行工夫 工具: Apche JMeter 【罕用】ApcheBench(ab)命令行工具【罕用】GatlingK6LocustWest Wind WebSurgeNetlingVegetaNBomber性能诊断 工具 VS自带的性能探测器CPU使用率回升的起因 while for循环 解决方案:应用Hash表寻存储数据 文件操作 解决方案:异步IO DoNetty 网络连接和网络数据传输 解决方案:应用缓存的形式存储数据 或者 应用异步IO多路复用机制 CPU使用率回升的缺点: 解决接口并发量的能力降落 零碎的吞吐量降落 性能排查落地 条件 NET CORE 3.1 SDK 或 更高级版本dotnet-counters 查看托管内存的应用状况dotnet-dump 收集和剖析转储文件步骤 创立内存溢出我的项目装置dotnet-counters 筹备 dotnet tool install --global dotnet-counters找到过程编号 dotnet-counters ps监督过程 dotnet-counters monitor --refresh-interval 1 -p [过程编号]最初查看显示统计信息 找到GC Heap Size 统计这个程序的增长,为了找出内存溢出的代码。 dotnet-dump 装置 dotnet tool install --global dotnet-dump 而后执行我的项目接口 ...

March 29, 2022 · 1 min · jiezi

关于性能优化:有关性能优化的感悟

下半年换了个工作环境,而后有了些新的感悟。在元旦这天,总结一下这几个月为了进步程序性能,而做的那些事。 1. 异步线程刚入行的时候,很烦面试的时候被考多线程,毕竟过后很少在工作中用到。但工作几年后发现,只有想进步程序的性能,就绕不开它。最常见的场景,就是利用多线程并发执行多个部分事件,缩短总体实现工夫。开发中,通常整个我的项目注册一个线程池的 Bean,各个办法都基于这个线程池来拿线程执行业务,容易针对线程池做参数调优。 有返回参数的异步,能够试试 CompletableFuture,也是 jdk8 提供的神器,比传统的 Feature 要好用,用法参考 CompletableFuture 教程。例如:当接口须要从多个内部零碎取数据时,都能够异步执行,而后对立收集返回值。甚至利用 CompletableFuture 中个性,主动执行回调办法。 但要留神,也不是什么时候都要用异步: 机器 CPU 资源无限:单台机器 CPU 的外围数无限,当多线程并发数达到顶点时,再加线程,反倒事与愿违。此时能够思考负载平衡,将并发线程摊派到多台机器上。同步更快:有些程序本来执行就很快,加了异步后反而慢了,毕竟调配线程资源也是须要工夫的。例如总共只有十几条数据,流运算时不必 stream,而是 parallelStream。2. 缓存中间件RedisRedis 是最罕用的缓存中间件了,它反对的罕用数据结构挺多,要依据理论利用场景来抉择,我目前用的有String、Hash、Set、List。 原始数据当然落在关系数据库中,但业务上罕用的,通常是通过转化的两头数据。例如:员工登录后所属部门、角色权限、积分等数据,来自于不同的微服务,不能每次要用都调各方服务的接口,这些都须要缓存起来。 用缓存很无脑,但刷新缓存才是难题。像刚刚的例子,不能把所有的缓存数据都落到员工的粒度上,要依据业务来分层。例如:机构级别的数据,就每个机构存一份,依照员工所属机构来查;部门级别的数据,就每个部门存一份,依照员工所属部门来查。等等。 Elastic Search用 ES 做缓存?预计很多人是大大的问号,谁让 Redis 过后不反对 Json 呢。从关系型数据库抽离进去的数据有时比较复杂,例如:人员所属的部门、角色、岗位等,每一个属性往下,背地的数据都不少。有人说 Redis 缓存个部门ID、角色ID,剩下的依据ID查表。但这些可是根底数据,且不说会不会把数据库查出问题,如果想要依据部门属性、角色属性、岗位属性来查人员,这个SQL该咋写。 最好的形式就是将这些数据从关系数据库中抽出来,以 Json 文档的模式缓存下来,MongoDB、ES 都无能这事。但为了应答后续可能千奇百怪的查问场景,还是 ES 保险一些。 可 ES 毕竟不是业余的缓存中间件,我很看好最近新进去的 RedisJson。齐全满足日常工作需要,而且据说查问性能是 ES 的上百倍。但毕竟刚进去怕有坑,等稳固一段时间再动手吧。 3. 消息中间件这里不说 MQ 的其余个性,就聊优化性能吧。后面说单台机器的 CPU 资源无限,能够思考将并发线程摊派到多台机器上,具体怎么做呢? 将须要解决工作通过音讯投递到 MQ 中,消费者监听到 MQ 的音讯后理论执行。假使有1000个工作,单台机器能解决工作的最大并发线程数是100,那么10台机器就够了。 4. 缩小零碎交互内存运算是最快的,要尽量减少和内部零碎的交互次数。 例如:在查问一批数据时,每条数据须要通过外键,查问匹配的其余零碎信息。如果其余零碎信息品种不多的话,是不是通过查一次SQL或调用一次接口,一次性全拿过去。而后写代码做数据拼接。而不是遍历出每条数据,都去内部零碎查一遍。 还有一些插入 MySQL、Redis 的一批数据,或给 MQ 发一批音讯的,如果能够的话,就在程序外部解决好,而后调用批量插入、发送的办法,性能相对能省不少。 5. Jvm 调优这是陈词滥调啦!我之前文章有写过,网上材料更多,这就不说了。只说一点,尽量少狐疑 Jvm 调优能进步你的程序性能,多从方案设计和代码上反思。 ...

January 31, 2022 · 1 min · jiezi

关于性能优化:增效降本开源节流2022年技术趋势前瞻异步编程容器技术

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_204 2022初始,凛冬已至,疫情横跳, 环境简约,君不见互联网大厂纷纷裁员,银根紧缩。这所有归结为两个字:老本。对于互联网企业来讲,除了最根本的工商财税,办公室、办公设备、人力、产品和公关等等,这一切都是老本。而在疫情因素侵入导致经济下滑的状况下,降本增效就曾经成为2022开年很多企业管理者非常重视的 KPI指标,而降本也肯定会成为2022年技术倒退的一个必然趋势。 降本增效,到底降什么本,增什么效,有何妙计? 异步编程始终以来,异步编程都是最有教训的开发者的特长,他们手不释卷地钻研着非线性执行流中的回调办法,念兹在兹的,不过就是无限资源下每秒解决申请数的晋升。异步编程形式兴许是开发者对本人的严格要求,但带来的收益无疑也是十分可观的,以Python的web开发畛域为例: 2021年web框架性能排行榜中,排名前十的无一例外全副是异步框架,所以,异步编程形式能够给咱们带来什么?是更高的每秒解决申请数,而更高的每秒解决申请数又能带给咱们什么?是更低的服务器老本。 那么异步编程到底怎么帮咱们节约资源呢?实质上,异步晋升的是服务器的吞吐量,而并非零碎的性能,因为,CPU密集型的异步工作和同步效率差不多,也就意味着异步这是资源利用率晋升,而非零碎性能真的晋升了。如果应用同样的CPU资源,解决同样的资源也会破费同样的工夫。假如同步意味着大量的阻塞,此时CPU的资源利用率较低,吞吐量也会同比升高。如果应用异步,那么CPU很容易就能拉满,此时吞吐量就会升高。 打个比方,京津高速双向八车道,日均车流量近5万车次,这里有个大前提,所有车道都得有车通行才能够,可是如果车辆基本就不变道,单向通行只用其中的两个车道,那多进去的两个车道意义何在?无疑是老本的节约,大多数状况下,高并发场景下的同步编程形式就是在节约系统资源。 再者,如果一套服务不能无效利用一台服务器的资源,那必然须要更多的服务器通过运行更多的利用实例来补救需要缺口。 例如一个百万日活服务利用,假如同步框架单台机器能够抗住400-500并发,大抵须要七台服务器能力堪堪挡住,如果应用 Python 异步框架,重构后由原来的 七台服务器削减至三台,老本骤降 57%。而一台8核16G,10M共享带宽的百度智能云BCC计算型服务器,预付费一年的价格大略为1.2万人民币。 假如咱们不思考服务器硬件老本,那也会由此引发出效率老本的耗费。当服务器数量重叠到肯定规模后,如果不改良底层逻辑和实现,无脑加机器其实是徒劳,并且运维老本会骤然减少,大批量服务器的监控、继续集成、继续部署都将会是不小的开销。 综上,想要降低成本,异步编程就会是那一把要害的锁钥,当然了,相应地,对于开发人员的综合业务能力的要求也会有肯定的进步,兴许有的人认为异步编程会升高开发效率,异步写法也会升高代码可读性,殊不知,学贵大成,不贵小用。如果感觉异步编程艰涩难懂,可读性差,兴许应该自我归因,致力晋升本人以适应新时代的编程形式才是王道。 容器技术容器,解决了利用打包标准化以及公布标准化的问题。早年间虚拟机形式的标准化水平是远远不够的,Docker容器终结了这一问题。随着 Docker 的一直演进和推广,在利用编排、资源调度等层面又呈现了新的问题,晚期的 Docker Swarm、Mesos 和 Kubernetes 相互竞争,最初 Kubernetes 胜出,并带来了新的资源编排方面的事实标准。在2022年的明天, Kubernetes 曾经成为一个事实标准。 标准化当前,Kubernetes上的业务类型越来越丰盛,从最后的无状态到起初的有状态,现在像人工智能这样比较复杂的计算引擎也都放在 Kubernetes 上了,这就是一个相互促进的过程,这下面的负载类型越来越多,整个 K8S 体系也的确变得越来越简单,但它可能治理的货色也越来越多。如果所有用户都摈弃传统部署形式,齐全应用容器,那容器的复杂度必然会晋升。 但对于互联网企业来讲,要做的就是在容器能做更多事件后去升高它的复杂度和老本,否则容器的门槛就会十分高。当初,无论是阿里云、百度云还是腾讯云都在思考从智能运维角度做更多的致力。比方在集群治理方面,如何用智能运维的形式发现以后运行中的一些情况,并且可能给出解决方法。当初也有智能利用画像和资源画像形式进步资源利用率。 综上,智能化运维也会是2022的一个根本技术趋势,而围绕容器的生态能够认为是将来最重要的技术走向之一,它必然会引起一系列的变动,包含企业外部组织的变动。咱们会看到,不仅整个运维管理体系在变动,企业外部也会呈现新的组织状态,比方 Google 提出的 SRE 团队就是为可用性负责。当初很多深度应用云原生的企业,包含阿里,都有专门的 SRE 团队,这个团队会负责整个可用性相干能力的建设。其次,企业也会呈现一些平台横向性的部门,基于云原生体系去撑持上方业务的部门。以前有些企业可能是偏竖井式的业务单元,即一个业务单元上面有撑持团队,容器包含 K8S 会让企业外部有更多平台横向型部门的呈现。这也是解决复杂度的一个办法,因为不是每个纵向的业务部门都有足够的资源投入和业余度去解决这个问题。企业足够大的时候肯定要思考在 SRE 层和平台建设层造成横向部门,进行职能拆散。 回到降低成本的主题,互联网企业能够改良的计划其实有不少。从偏底层看,很多云厂商和头部互联网公司在自研芯片,华为的例子通知咱们,进口芯片不仅会导致老本溢出问题,玩不好可能连生命线都被人掐断,所以 软件硬件联合一体能力带来基本上的降本增效。另外就是容器化操作系统,这个畛域能够了解为容器技术的一个分支畛域,它是基础设施层面一个比拟重要的优化办法,升高了操作系统装置、适配以及稳定化的老本。 此外,弹性利用技术是很多云厂商宽泛应用的降本增效的办法。很多互联网公司在尝试弹性离在线混部技术,实质上还是进步服务器利用率。之前各个公司在自购服务器或者云上购买云服务器的利用率往往都低于 10%。这个利用率并不高,很多公司尝试去推高这个水平线,但推高水平线必然会带来很多技术挑战,比方利用率高了之后,多种负载混合跑时,是否会相互影响。几大厂商都在通过开源或商业化产品模式尝试输入离在线混部(多种负载混合部署)技术,置信在2022年,离在线混部技术将迎来进一步的产品化顶峰。 结语:降低成本这件事件其实是所有资本家永远的诉求,只不过当公司在起步或者高速倒退的阶段这个诉求并没有那么强烈,会以业务后行。然而随着业务进入安稳期或者遇到大环境的限度时,降本需要会更显著,所以2022年,通过异步编程形式以及容器的技术的改良,晋升服务器利用率从而降低成本会是大趋势。是的,不计成本一门心思搞科研的时代兴许曾经过来了,就像某部香港电影里说的那样: 没错,我是小角色来的,你能够回绝我,然而,你能够回绝这个时代吗?原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_204

January 14, 2022 · 1 min · jiezi

关于性能优化:基于-PageSpeed-的性能优化实践

前言网站性能至关重要,会影响 SEO 排名、转换率、用户跳出率以及用户体验等。在浏览器中加载迟缓的网站可能会缓缓失去用户,相同可能疾速响应的网站通常会有机会获取更多流量,带来更大效益。 最近咱们在站点做了一版性能优化,把次要着陆页面的 PageSpeed 分数从本来 30 左右晋升到 80 分以上。 在这里分享下在这个过程中的一些教训,介绍下咱们是如何达成这个后果,其中又波及到哪些技术。 文章将从性能指标、性能测量与优化实际计划三个方面开展,冀望能够给大家提供一些思路与参考。 性能指标性能指标的倒退与演进针对线上我的项目做性能优化,首先须要有一个确定的可量化的评判规范,用以来判断优化工作是否无效。 传统的性能指标最典型的是 DOM Ready 工夫 和页面加载工夫(load time):前者指的是初始 HTML文档被齐全加载和解析实现,个别是通过监听 DOMContentLoaded 事件取得;后者指的是整个页面所需的资源(包含脚本、款式、图片等)加载实现的工夫,通过监听全局的 load 事件获取。 在新近前后端耦合的时代,是通过在服务端应用模板引擎渲染出 HTML,能比拟好地反映网站性能。起初前端畛域的迅猛发展,尤其是随着客户端渲染计划的流行,以及各种动静技术的大量使用,这两个指标差不多曾经失去其原有的意义,无奈精确反映性能。 起初浏览器提供了 Navigation Timing API ,通过 perperformance.timing 能够获取从页面开始加载到完结整个过程中不同阶段的工夫点。这很不错,开发者能够从多个维度去定义一些指标,通过简略的差值计算去监控站点性能。 比方在外部的用户行为追踪脚本(UBT)中就基于 timming API 次要定义了以下 7 个要害指标 DNS Connect Request Response Blank Domready Onload DNS (domainLookupEnd - domainLookupStart)Connect (connectEnd - connectStart)Request (responseStart - requestStart)Response (responseEnd - responseStart)Blank (domInteractive - responseStart)Domready (domContentLoadedEventEnd - navigationStart)Onload (loadEventEnd - navigationStart)同样,这些指标更侧重于技术细节,并不能很好地反映用户真正关怀的问题。在做性能优化的时候,很可能面临的一种场景是,曾经把某些特定指标如加载工夫的数值大幅缩小,但用户体验依然很差。基于此,Chrome 团队和 W3C 性能工作组推出了一组 以用户为核心的性能指标,从用户角度更好地去评判页面性能。 ...

January 3, 2022 · 3 min · jiezi

关于性能优化:三年磨一剑高德地图体验优化总结

作者:杨夕凯、吴文扬 高德地图从19年开始对全链路性能体验进行了继续三年的优化,最终整体外围链路上实现了打对折优化,用户体验上大幅晋升。过程中,对性能优化的一些思考和实践经验,本文进行了总结,心愿对大家有些助益。 优化前后成果比照(以优化前的耗时为基线100%) 思路整体思路分为明确性能卡点,倒序专项解题和正序长线管控三个局部: 明确性能卡点: 找到优化点能力对症下药,迷信的评测规范和明确的优化点对于优化至关重要,迷信的评测规范须要可能正当评估性能体验的好坏,并更贴近用户的实在感触,而指标则须要可量化,这样才可能保住在专项过程中疾速对焦高效执行,防止走弯路;倒序专项解题: 性能问题不是繁多业务问题,往往波及多个产研测团队合作,咱们从问题登程疾速倒序以专项模式凝聚多团队资源,确定指标,疾速攻坚拿后果,加强团队信念;正序长线管控: 优化是从“果”倒退“因”的过程,曾经产生问题了再去解决,是一种倒序解题的思路。那么如何让问题从“因”的源头上截住,或者说让曾经优化的成果不产生倒退,那么咱们的思路三是:长线继续的正序管控,防止原有业务的继续好转,同时坚固专项的优化成绩。接下来,本位将针对这三个局部,逐个解析。 明确性能卡点制订规范首屏加载速度的快慢极大影响着用户体验,所以首屏耗时作为咱们页面耗时的统计规范。随着手机硬件的一直降级,很多高端设施硬件性能好覆盖了程序性能问题,因而咱们会对不同机型等级设施进行优化,最大水平的笼罩到线上用户。 统计规范确定了首屏显示耗时是统计规范,上面是如何确定首屏显示耗时的几个维度: 业务角度:业务形态各异,不同页面的首屏定义肯定不同;产品角度:定义首屏围绕着性能使用量进行,高频性能优先;研发角度:通过业务流程上的日志埋点来锚定首屏的起起点;产研测拉通规范:建设对立的产研测沟通语言,那就是量化数据。机型规范机型等级:依据设施评分将设施分为高中低三种等级;选定机型:选定不同等级代表机型的准则,咱们采取的是根据线上用户设施的占比,尽可能的笼罩比拟多的用户,尽可能选取有代表性的厂商设施,当然也须要综合思考现有测试实验室可用设施状况,毕竟洽购不肯定很及时和防止不必要的节约。确定优化项高德地图长期以来的历史累计,导致每个场景的优化,都面临着简单的业务代码,甚至还存在业务盲区。这就对疾速剖析历史大量业务,精确定位耗时点带来极大的挑战。如果靠人工梳理剖析,人力投入和时长都不事实。这就须要从工具和方法论上找到减速计划。 自上而下明确优化点手机设施维度剖析:有限的业务场景通过挪动设施运行在无限的性能资源上,资源分配势必顾此失彼。所以咱们须要依据设施的不同来剖析耗时问题。比方在比拟差的手机上呈现的耗时问题,可能在高端的手机上并不是问题。优化点也不同,须要个性化策略来进行针对性优化。例如:低端机的简单交互动画就是一个耗时点,比方搜寻页面敞开一些动画,性能上带来不小的收益,同时也不侵害用户体验,在高端机上这个耗时点就能够不思考。 业务平行维度剖析:业务点特地多,那么为什么咱们要抉择出行场景、搜寻场景等去剖析耗时呢?这就须要拉通产品和BI,用数据谈话。通过分析线上用户行为,大部分用户抉择了点击搜寻框进入搜寻首页,而线上用户反馈也是进入搜寻卡顿耗时等,相比其余性能,搜寻首页的及时性和重要性显而易见,于是依据线上数据进行业务分级,该场景排在首位,性能资源应该向这里歪斜,须要首先剖析这里的耗时点。 业务外部维度剖析:首先对业务场景自身进行全链路梳理,找出其中的要害工夫点,而后通过场景日志工具进行埋点并上传至服务,收集线上用户真正的首屏工夫数据,为量化指标提供无效根据。其中两两关键点之间的工夫戳差值即为阶段耗时,能辅助剖析业务耗时问题。围绕着业务剖析的过程咱们还积淀了很多剖析工具来辅助剖析。 最小集,加法,减法 最小集是一个探底的过程,在保障首屏产品状态不变形的状况下做出最小可运行,去掉其余所有跟首屏无关项,这就是减法。咱们能够了解这个最小集是在不扭转现有架构的状况下,咱们最优的优化成果。如果最小集的极限数据达标,接下来就要在此基础上把必要的相干依赖项一一加回来,保障产品功能完善,其余没必要的依赖性能够优化、或者去掉、或者延后等,这就是加法。当然如果这个最小集的极限数据都不能达标,那咱们就须要从其余维度去寻找优化点了,个别可能从网络耗时和架构合理性两个方面找到突破点。 倒序专项解题性能问题不是繁多业务问题,往往波及多个产研测团队合作。所以咱们的思路是: 从问题登程疾速倒序以专项模式凝聚多团队资源,确定指标,疾速攻坚拿后果,加强团队信念 专项攻坚专项攻坚,也是个边打边建,边打边积淀的过程。排查性能问题的伎俩最后是比拟离散的。往往是遇到一个解决一个,下次不同的场景须要反复工作再来一遍,那么咱们的思路是: 积淀可复用计划,解题思维、通用框架和工具平台,针对“优化伎俩”自身的效率进行优化,让老本逐步升高 启动专项是第一个性能专题我的项目,实现了一个场景优化,消耗30人,3个版本迭代。之所以人力比拟多,是因为“第一次”面临的问题十分多,指标要剖析定义规范、埋点工具要新建、优化过程没教训、管控伎俩要新建。 搜寻专项实现了一个场景优化,消耗8人,人力状况就好了很多,版本变成2版。过后曾经有启动期间曾经建设好的埋点工具,有了肯定的优化教训,少走了很多弯路。 外围链路专项实现了六个场景,消耗24人,一版搞定。优化的过程井井有条,人力少、场景多、工夫短。这得益于优化效率的晋升,老本逐步升高。在一直优化的过程中积攒了绝对成熟的剖析工具、优化工具、管控工具。 优化计划性能优化是一个体系化问题,咱们在优化计划上分为三层,业务、引擎和根底能力,别离自上而下明确优化点。下层业务进行自适应资源调度,两头引擎提供减速能力,底层能力提供高性能组件。 业务自适应资源调度业务层优化次要通过业务编排调度来实现性能最优状态,但业务各自调度优化工作反复且繁琐。为了升高这部分老本,咱们开发了一套资源调度框架,业务接入后,调度工作由框架实现。调度框架在利用运行过程中,感知采集运行环境,而后对不同环境状态进行不同的调度决策,生成相应的性能优化策略,最终依据优化策略执行对应优化性能。与此同时,监测调度上下文以及调度策略执行成果,并将其反馈给调度决策零碎,从而为进一步的决策调优提供信息输出。这样,能够做到在不同的运行环境下都能达到可预期的极致性能体验。 一、环境感知感知环境分为硬件设施、业务场景、用户行为和零碎状态四个维度: 硬件设施上,一方面通过团体实验室对已知设施进行评测跑分,以此确定高中低端机型,另一方面在用户设施上本地对硬件进行实时算力评估;业务场景上,将业务分为前台展现、后盾运行、交互操作等几类,个别状况下前台正在进行交互操作的业务场景优先级最高,后盾数据预处理业务场景优先级最低;对于同类别业务场景,依据业务UV、交易量、资源耗费等维度进行PK,确定细分优先级;用户行为上,联合服务用户画像和本地实时推算,确定用户性能偏好和操作习惯,为下一步针对用户的精准优化决策做筹备;零碎状态上,一方面通过零碎提供接口,获取诸如内存正告、温度正告及省电模式等来获取零碎极其状态,另一方面通过对内存、线程、CPU和电量进行监控,来实时确定零碎性能资源状况。二、调度决策感知到环境状态之后,调度零碎将联合各种状态与调度规定,进行业务以及资源调配决策。 降级规定:在低端设施上或者系统资源缓和告警(如内存、温度告警)时,敞开高耗能性能或者低优先级性能避让规定:高优先级性能运行时,低优先级性能进行避让,如用户点击搜寻框时到搜寻后果齐全展现的时间段内,后盾低优工作进行暂停避让,保障用户交互体验;预处理规定:根据用户操作及习惯进行预处理,如某用户通常在启动3s后,点击搜寻,则在3s之前对该用户搜寻后果进行预加载,从而在用户点击时出现极致的交互体验成果拥塞管制规定:在设施资源缓和时,被动升高资源申请量,如CPU忙碌时,被动升高线程并发量。这样在高优工作到来时,避免出现资源紧缺申请不到资源性能体验问题三、策略执行策略执行分为工作执行和硬件调优:其中工作执行,次要是通过内存缓存、数据库、线程池和网络库对相应工作的进行运行管制,来间接实现对各类资源的调度管制;而硬件调优,则是通过与零碎厂商单干,间接对硬件资源进行管制;如CPU密集的高优业务开始运行时,将进步CPU频率,并将其运行线程绑定到大核上,防止线程来回切换损耗性能,最大化地调度系统资源来晋升性能 四、成果监测在资源调度过程中对各个模块进行监测,并将环境状态、调度策略、执行记录、业务成果、资源耗费等状况反馈给调度零碎,调度零碎则以此来评判本次调度策略的优劣,以做进一步的调优 引擎减速能力一、地图引擎地图引擎是地图利用独特的局部。这块次要从绘制优化策略动手,次要包含分批分块渲染、帧率调度、音讯调度等。 二、跨端引擎跨端引擎则须要给业务提供撑持,它也是全场景通用的计划,比客户端优化更有施展空间,与业务间接接触离业务够近。所以跨端引擎的优化策略就是升高业务代码的性能老本。次要计划有: 线程提优先级上下文预加载业务框架复用require援用复用这里简略介绍下上下文预加载,为了不影响现有业务的运行状态,咱们设计了一种闲时分段预加载的计划,可能在页面未进入之前,将页面须要计算的耗时、导入文件的耗时等提前执行。 闲时:当业务线程闲暇时再做预加载,防止影响其余页面分段:每次预加载的内容粒度小于16ms,防止预加载工作阻塞以后线程预加载:将指标页面的计算量提前,减速进入指标页面三、H5容器1、离线包减速 离线包减速,次要解决简单 H5 页面的加载速度问题:资源文件数量较多,下载耗时较长,导致页面加载迟缓,通常通过减少loading来缩小界面加载期待问题,从而导致用户期待耗时长,最终带来的是转换率散失。在此大背景下,联合高德已有的一些平台能力,搭建了离线包减速能力。整个链路蕴含: 离线包构建:通过前端脚手架,提速业务开发效率,动静指定离线包资源配置;离线包公布:对接已有的服务公布能力,搭建前端可视化公布平台,提供灰度管制、包更新、数据统计等能力;端治理:包下载、治理、失效,管制下载及更新机会——对于高频页面进行预下载申请,关上页面时实现“秒开”;资源失效:容器内资源加载拦挡,对接离线资源管理模块,命中缓存则间接失效,未命中走失常网络申请进行下载。2、容器预创立 容器的预创立和预热,对于H5页面的加载速度将会有很大的晋升,WebView的实例创立老本自身是绝对较高的,在APP启动后适合的机会进行预创立并缓存复用,能够解决首次开启和二次加载的速度。AMap自身有启动工作编排及闲时任务调度,在此基础上可在对应WebView模块内进行预创立操作。对于预创立WebView Context切换问题,因为AMap的页面栈理论为自定义实现,仅有一个独立的Activity,因而具备人造的良好兼容性。对于预创立,自身是空间换工夫的一种做法,对于不同性能设施的差异化配置,须要重点打磨——此外,也能够联合端智能的特色行为,相似用户页面跳转的行为习惯及频次等,来动静决策是否须要进行预创立。 架构高性能组件一、线程池线程池反对业务进行工作优先级编排、线程总数管制、线程避让等调度策略,使设施资源失去充沛正当的利用。 线程队列治理模块,其提供5个优先级队列: 高优队列:用于解决 UI 相干的工作,可能疾速返回执行后果,如启动阶段高优工作等;次高优队列:用于执行须要立刻返回的工作,如业务page文件加载等;一般(低优)队列:次要用于不须要立刻返回的工作,如网络申请;后盾(最低优)队列:用于解决一些用户不会感知的工作,如埋点、耗时的IO操作等;主线程闲时队列:用于解决不须要立刻执行,但业务又不反对按需执行的工作,只有在主线程检测处于闲暇状态时才会执行二、网络库网路申请作为场景中耗时大头,其性能体现简直决定了场景首屏耗时体现,咱们针对网络申请的各个环节,做了链路监控与极致优化,重点蕴含:申请精细化调度、并发预处理、DNS预加载、连贯复用等。 申请链路示意图: 排队:对申请进行精细化调度;对线程资源分级,高优申请有本人独立的资源,同时资源能够高占低,但低不能占高,实现高优申请 0 排队。同时限度低优申请并发量,防止并发过多导致底层带宽抢占;预处理:次要蕴含公参、签名、加密等一系列耗时操作,将预处理操作从原来的串行转为并行,压低预处理耗时;DNS解析:罕用域名做白名单,在启动时即会进行罕用域名DNS预解析,真正应用时,实现解析0耗时;建连:通过应用h2长连贯、预建连等策略,实现建连简直0耗时;申请上/上行:依据body大小,智能判断是否须要压缩,升高body大小,缩小传输耗时;解析回调:针对响应较简单的场景(如布局),应用更高效的数据协定格局(如pb),升高数据大小&解析工夫。正序长线管控优化是从“果”倒退“因”的过程,曾经产生问题了再去解决,是一种倒序解题的思路。那么如何让问题从“因”的源头上截住,或者说让曾经优化的成果不产生倒退,那么咱们的思路三是: 长线继续的正序管控,防止原有业务的继续好转,同时坚固专项的优化成绩。 高德地图客户端横向业务上蕴含出行、搜寻、打车等业务线,纵向架构上蕴含业务层、平台适配层、跨端引擎层和地图引擎层,跨多个语言栈,性能问题具备跟进流程长和排查链路长的特点。因而管控思路集中在规范、流程、自动化平台和工具的建设上。 []() 规范在通过全面的专项治理后,性能管控的指标和要求是防止继续好转的状态,因为测试稳定的存在及热更、疾速迭代、动态化插件的频繁公布,须要管控的进口十分多,如果存在管控脱漏区,性能就会不可避免的继续好转。因而管控规范确定为以固定基线为基准,以环比数值为量化规范,把所有变动因素都蕴含到管控中,无效避免叠加好转。 流程高德客户端主版流程次要分为三个大阶段:需要剖析和设计、业务独立迭代开发、集成测试,集成测试阶段自身有大量的业务BUG,所以留给性能问题发现和解决的工夫十分缓和,为了解决这些问题,管控流程须要利用好主版流程的每一个阶段,分阶段毁灭性能问题。 需要剖析和方案设计计算,提前辨认问题;迭代开发阶段,提前发现和解决问题,升高性能问题裸露晚导致来不及修复,影响线上用户体验的危险;集成测试阶段每天汇总数据大盘,及时发现问题,依靠平台和工具疾速排查,减速问题流转;灰度和公布阶段关注线上数据大盘,建设报警机制,及时发现问题,通过用户日志排查线上问题。平台依靠泰坦继续集成平台和ATap自动化测试平台,打造连通开发,构建,性能测试,问题跟进、排查、流转、解决残缺链路的工具链,进步问题发现和解决的效率。 泰坦继续集成平台 定时构建,反对定位出包工作,构建类型反对性能包自动化测试触发,反对打包触发和定时触发两种触发形式集成卡口及决策,集成申请展现性能测试后果,集成决策审批流程ATap自动化测试平台 性能大盘,汇总性能数据,疾速发现问题埋点详情,整合疾速排查工具,减速排查问题跟进,联合Aone,监控问题解决流程,减速流转 总结目前为止,高德外围链路的性能体验优化成果失去了较大的晋升。从最后的拿到优化后果,到起初的优化效率晋升,优化老本升高。整体的优化过程总结下来: 战术上,采纳“专项”+“技术积淀”+“长线管控”的形式,可能保障性能体验问题失去良性解决。策略上,过来咱们靠“人”解决问题,当初咱们靠“人”、“架构”和“工具”解决问题。将来是否可能“工具”本人解决问题或者避免出现问题呢?随着“技术积淀”积攒的工具和“长线管控”建设的平台一直减少,置信质变引起量变只是工夫问题。关注【阿里巴巴挪动技术】微信公众号,每周 3 篇挪动技术实际&干货给你思考!

December 23, 2021 · 1 min · jiezi

关于性能优化:巧用esnext可以在开发过程中提升效率和优化性能-springboot实战电商项目mall4j

springboot实战电商我的项目mall4j (https://gitee.com/gz-yami/mall4j) java开源商城零碎 巧用esnext能够在开发过程中晋升效率和优化性能,简略分享下esnext局部知识点(依据本人了解分享,不齐全按es版本程序) 【ps:其实ESNext是⼀个泛指, 它永远指向下⼀个版本. ⽐如以后最新版本是ES2021, 那么ESNext指的就是2022年6⽉将要公布的规范。 但在这里因为想分享的“新”个性自es6到最近的都有波及,所以权且统称esnext(不是指下一个新规范的内容我没那么快...也不是指js的库)】 一、解构赋值1、数组构造在之前给数组赋值个别会这样写: const arr = [1,2,3]let a = arr[0]let b = arr[1]let c = arr[2]console.log(a,b,c) // 1 2 3当初用es6能够这样写: let [a,b,c,d] = [1,2,3,4]console.log(a,b,c,d) // 1 2 3 4// 还能够这样写let [a,[b,c],d] = [1,[2,3],4]也就是说,只有等号两边的模式雷同,右边的变量就能够被赋值与左边对应地位上的值,这实质上属于“模式匹配”。 如果等号右边的变量在等号左边的对应地位上没有找到有效值,就会解构不胜利,比方像这样: let [a,b] = [1] // 变量b没有在左边对应地位上找到无效的值,b会等于undefined而如果反过来,等号右边只匹配等号左边数组的一部分,这种状况叫不齐全结解构,并且能够解构胜利: let [a,b] = [1,2,3] // 匹配前两项console.log(a,b) // 1 2 let [x,,y] = [4,5,6] // 匹配第0项和第2项consoleg(x,y) // 4 62、对象解构对象解构与数组解构不同的中央在于:数组是有秩序的,所以数组解构是按地位取值;而对象的属性是没有秩序的,所以对象解构是用变量名对应属性名的形式来取值,也就是先找到同名属性,再赋值给对应变量,像这样: let {a,b} = {a: 'a1', b: 'b1'}console.log(a,b) // a1 b1// 秩序不同,找到同名属性就能够赋值给对应变量let {d,c} = {c: 'c1', d: 'd1'}console.log(c,d) // c1 d1// 谬误示例:let {f} = {a: 'a1', b: 'b1'}console.log(f) // undefined如果想要应用不同的变量名来获取等号左边的某个属性值,也能够这样写: ...

December 2, 2021 · 5 min · jiezi

关于性能优化:基于XamarinAndroid的应用程序启动性能优化

背景随着挪动应⽤程序开发越来越流⾏, 越来越多的应⽤程序浮现于市场。 然而, 开发挪动应⽤程序 并不是⼀个简略的过程, 须要破费⼤量工夫, 尤其是如果想要⼀个可跨 Apple、 Android 和          Windows 运⾏的可扩大挪动应⽤程序。 然⽽, 蹩脚的性能可能会极⼤地侵害⽤户体验。 ⽤户在任何时候都不心愿看到 10 秒以上的启动 画⾯。 如果等待时间过⻓, 他们可能会感到⽣⽓、 放弃购物、 缩小停留时间或齐全卸载应⽤程    序。 随着开发平台的遍及, 咱们须要正确的⼯具和⽅法来满⾜一直增⻓的需要。 Xamarin 就是这样⼀种框架, 它⽀持在 Android、 iOS 和 Windows 平台上共享单个代码库。 所以, 咱们将在 Xamarin.Android 应⽤程序中测试性能, 就像在 Android Studio 中使⽤ Java 开发⼀样, 咱们能够使⽤c#对性能进⾏测试, 从⽽优化启动工夫。 测试总启动工夫 ⾸先测试程序在不同设施的启动工夫, 此处⽤到的⼯具是友盟+推出的U-APM。 从图中能够看 出应⽤程序在启动工夫上还存在着⼀定的优化空间。 在 Android 上, ActivityManager零碎过程会显示⼀条“初始显示工夫”⽇志音讯, 能够更好地了 解整体启动工夫。 在命令⾏使⽤adb logcat疾速查看 Android 设施⽇志。 或者使⽤Visual             Studio 中的Android 调试⽇志。 ...

November 12, 2021 · 2 min · jiezi

关于性能优化:巧用友盟UAPM-实现移动端性能优化启动速度

简介:挪动端性能对用户体验、留存有着至关重要的影响,作为开发者是不是被这样吐槽过,“这个 APP 怎么这么大?”、“怎么始终在 APP 封面图转悠,点不进去”、“进入详情成果有些卡”、“用 4G 应用你们的 APP,我的流量有点不够啊”等等,这些问题都直观反映出,一个体验良好的利用,只有性能健全还不够,以下是我在性能优化上总结的几点: • 启动速度优化 • 晦涩度优化 • 资源优化 • 内存优化 • APK 体积优化 明天先聊聊,启动速度的那些事 利用启动流程冷启动从点击利用图标到UI界面齐全显示且用户可操作的全副过程。 特点:耗时最多,衡量标准 启动流程:Click Event -> IPC -> Process.start -> ActivityThread -> bindApplication -> LifeCycle -> ViewRootImpl 热启动因为会从已有的利用过程启动,所以不会再创立和初始化Application,只会从新创立并初始化Activity。 特点:耗时较少 启动流程:LifeCycle -> ViewRootImpl 因而判断利用启动速度的的规范是冷启动的速度,即杀掉利用后重新启动的速度,此项次要是和你的竞品比照。 不应在 Application 以及 Activity 的生命周期回调中做任何费时操作,具体指标大略是你在 onCreate,onResume,onStart 等回调中所破费的总工夫最好不要超过 400ms,否则用户在桌面点击你的利用图标后,将感觉到显著的卡顿。 冷启动剖析及优化方向冷启动波及的相干工作冷启动之前 首先,会启动 App而后,加载空白 Window最初,创立过程须要留神的是,这些都是零碎的行为,个别状况下咱们是无奈间接干涉的。 随后工作 首先,创立 Application启动主线程创立 MainActivity加载布局安排屏幕首帧绘制通常到了界面首帧绘制实现后,咱们就能够认为启动曾经完结了。 上面是官网文档中的启动过程流程图,显示零碎过程和利用过程之间如何交接工作。实际上对启动流程的简要概括。 优化方向 咱们的优化方向就是 Application 和 Activity 的生命周期这个阶段,启动中的零碎工作咱们无奈干涉,能干涉的就是在创立利用和创立 Activity 的过程中可能会呈现的性能问题。这一过程具体就是: • Application 的 attachBaseContext ...

November 12, 2021 · 1 min · jiezi

关于性能优化:Swiperjs插件轮播滑动卡顿优化

插件地址:https://swiperjs.com/ 场景:主动轮播几十个item,组件滑动卡顿显著,轮播个数为20个以下体现失常。 起因:轮播前,渲染所有的swiper-item,dom元素一口气循环挂载到dom树上,当swiper-item个数很多的时候,dom节点内存增大,监听事件占用的内存也逐步加大,所以呈现滑动卡顿景象。 解决方案:次要思维:简化dom构造。计划一: 应用api中virtual,开启虚构Slide性能。然而不适用于咱们以后的有限轮播。Note that according to Virtual Slides realization it doesn't work withloop mode, slidesPerColumn more than 1 and slidesPerView: 'auto'计划二: 窗口化思维,把没有显示进去的dom元素尽量简化,用空 <SwiperItem/> 代替。目前采纳计划二解决。具体实现:1、获取以后轮播的index。 on: { slideChange: function() { _this.swiperIndex = this.realIndex; }, }2、加载轮播窗口左近dom元素、数组中最前和最初三个swiper-item,其余用空 <SwiperItem/> 代替。 <Swiper options={options} onSwiperInit={this.onSwiperInit} className={s.slider} wrapperCls={s.wrapper}> {list.slice(0, len).map((item, index) => { return ( {(this.swiperIndex < index + 6 && this.swiperIndex > 6 || [len-3,len-2,len-1,0,1,2,3]).includes(index)? <SwiperItem key={index}> <div className={cx(s.item, 'swiper-lazy')} data-index={index}> renderItem(item, index) </div> </SwiperItem> : <SwiperItem /> ); })}</Swiper>为什么须要始终保留数组中最前和最初三个swiper-item?以后loop:true,有限循环模式,Swiper复制了两份swiper-item(slideDuplicateClass),别离增加在原始的swiper-item前后地位,然而slideDuplicateClass只在Swiper初始化的时候渲染,之后动态显示窗口左近的dom元素,无奈扭转slideDuplicateClass的dom的构造,就会呈现轮播到最初一个的时候空屏的状况。有限循环轮播的外围就在于头尾多出的两张图,从图三再向后滑动,会滑到红色图一,这个时候给用户的感觉就是无缝从最初一张滑动到第一张的,当他滑到占位图一时,咱们再霎时切换到粉色图一(即真正的图一),因为是霎时变换,用户是感知不到的。同理,从图一滑到图三也一样。 ...

October 9, 2021 · 1 min · jiezi

关于性能优化:用户实践-基于-MegEngine-移动端-CPU-的深度学习模型推理性能优化

用户实际系列,将收录 MegEngine 用户在框架实际过程中的心得体会文章,心愿可能帮忙有同样应用场景的小伙伴,更好地理解和应用 MegEngine ~作者:王雷 | 旷视科技 研发工程师 背景随着人工智能技术的倒退及应用领域的不断扩大,算力较弱的挪动设施成为模型推理的重要运算载体,优化其推理性能因而成为重要的工程问题。个别认为,让模型运行于 GPU 上会比运行于 CPU 上具备较大的劣势,获得可观的性能晋升。这通常是真实情况,然而,在工程实际中咱们也发现,对于某些模型维度较小的模型,在挪动设施上,GPU 运行并没有带来性能的晋升,而且还额定引入了兼容性的问题。所以,在某些利用场景下,咱们须要以 CPU 为运行载体,尝试各种办法,以晋升模型推理性能。 咱们在优化某关键点模型推理性能的工程实际中,基于 MegEngine 推理引擎,发现有两个优化办法比拟无效,NCHW44 和 Record。本文将对它们的原理和应用办法做比拟具体的阐明。 NCHW44 优化原理家喻户晓,减少计算的并行水平是晋升计算速度的重要伎俩。在 CPU 上,这就须要应用 SIMD 指令 ——Single Instruction, Multiple Data,单指令多数据,即执行单条指令,操作实现多个数据的运算。例如执行加法运算,如果应用非 SIMD 指令即个别的加法指令,每次只能操作一个数,而在模型推理中,这个数常常是 8 位、16 位,最大不过是 32 位的浮点数,这对于古代 64 位的寄存器来说,的确有些节约。如果在寄存器中存储多个数,一条指令实现运算,则能成倍的晋升计算速度。在 x86 CPU 上,SIMD 的实现是 SSE、AVX 等指令集,而在 ARM CPU 上,则是 NEON 指令集。而且 CPU 还提供了 SIMD 指令的专用寄存器,在 x86 平台上,寄存器位数为 128 位、256 位,甚至是 512 位,在 ARM 平台上,寄存器位数是 128 位,这样就能够一次实现 4 个 float32 数据的运算。因而,如果能想方法在模型推理运算中尽可能多的应用 SIMD,就能晋升推理的性能。 ...

August 17, 2021 · 2 min · jiezi

关于性能优化:渲染进程各处理过程的优化点

浏览总结,尽量简短,没事看一眼。 渲染过程JS 解决 JS 对 DOM CSSOM 的解决款式计算 解析 CSS 计算每一个元素的最终款式页面布局 款式计算完结后,开始计算每个元素的宽高、坐标绘制 布局计算完结后,就能够开始绘制元素了,包含文本、色彩、边框、暗影、图像等合成 依据元素的程序进行图层合成布局和绘制这两个过程是有可能跳过的,因为并不是所有的操作都会引发布局和绘制。 上面是一个 CSS 属性与布局、绘制、合成的触发关系 属性BlinkGeckoWebkitz-index绘制/合成绘制/合成布局/绘制/合成transform合成合成布局/绘制/合成opacity绘制/合成合成布局/绘制/合成min-width布局/绘制/合成布局/合成布局/绘制/合成color布局/绘制布局/绘制布局/绘制/合成background布局/绘制布局/绘制布局/绘制/合成border-radius布局/绘制布局/绘制布局/绘制/合成border-style布局/绘制/合成布局/绘制/合成布局/绘制/合成border-width布局/绘制/合成布局/绘制/合成布局/绘制/合成吐槽一下感觉 Gecko 还挺厉害。 款式计算优化缩小匹配的元素数量,尽量不要应用 * {}升高选择器复杂度,尽可能的应用繁多精准的类选择器应用 BEM 标准(BLock、Element、Modifier),例如:.banner\_\_header_size-3 {}布局与重绘优化布局又叫重排、回流,这里要通晓这两个也是指的布局这个渲染过程。 触发重排的操作: 批改 DOM 元素的几何属性 width、heightpadding、marginleft、top批改 DOM 树的构造 减少 DOM 元素挪动 DOM 元素删除 DOM 元素获取 DOM 元素的即便布局属性 offsetWidth、offsetHeight、offsetTop、offsetLeftclientWidth、offsetHeight、offsetTop、offsetLeftscrollWidth、scrollHeight、scrollTop、scrollLeftwindow.getComputedStyle()这可能更多的是对下面表格的一个补充,不过以后的角度是针对“操作”而言,下面的更多的是针对款式而言,那么既然晓得了此类操作会导致页面的回流,就应该更加审慎的对他们进行操作。 一个不错的计划是对 DOM 元素的几何属性的批改应该打包操作,不举荐逐条批改el.style.top = '...' 之类的操作,应该思考应用增加类来进行打包操作。 绘制性能评估能够应用 chrome 的 More tools -> Rendering 来进行绘制性能的评估。 合成影响合成性能的因素会有两个: 所需合成的图层数量实现动画的相干属性应用 will-change 能够通过创立新的图层起到绘制区域最小化的优化,chrome、firefox、opera 能够通过设置 .layer { will-change: transform;}来达到新增一个图层的目标;然而 safari 不反对 will-change,所以须要应用变通的办法来创立一个图层 ...

August 8, 2021 · 1 min · jiezi

关于性能优化:极客星球-应用开发的性能优化探索

▌前言 性能作为挪动端用户体验的关键因素,其优化问题始终困扰着大家。如何打造更好的用户体验,如何谋求极致优化、最佳的性能指标,如何在前人教训根底上持续翻新,开掘新的技术点,始终是这个行业的人在谋求和摸索的指标。 性能优化的过程分两局部:发现性能瓶颈 制定方案,解决性能问题 解决性能问题的计划须要具体情况具体分析,更重在教训积攒。本文将重点围绕“如何找到性能瓶颈”总结一些教训办法,帮忙大家疾速发现问题,疏导更多思考和探讨。 ▌如何找到性能瓶颈 罕用的性能检测工具是traceview,集成于“Android Device Monitor”中。从Android Studio3.0开始,“Android Device Monitor”被废除,取而代之的是“Android Profiler”,其中提供了“Memory Profiler”、“CPU Profiler”、“Network Profiler”三大性能。 内存优化(包含内存透露)罕用的是 MAT 或者 LeakCanary ,而 Memory Profiler 相当于将 MAT 的简化版性能集成到 AS 中。绝对的在性能优化方面,CPU Profiler 相当于将 traceview 的性能集成到了 AS 中。 所以,应用AS3.0之前版本的,能够应用traceview,而应用AS3.0当前版本的,除了traceview,还能够抉择CPU Profiler。 如果想追踪零碎过程的具体数据,以解决帧引起的界面卡顿等问题,能够应用 “systrace” ,本文不做波及。可参考文末标注①② ▌traceview 应用办法 应用 traceview 须要首先应用 “Debug” 类进行 “插桩” ,当利用执行到被插桩的代码时就会在手机sdcard中主动生成 “.trace” 文件,之后应用 traceview 或者 AS(3.0以上版本)关上文件即可。 一、插桩 插桩须要应用到 “Debug” 类,并且会在 sdcard 中生成 “.trace” 文件,所以你必须首先保障你的利用具备写内部存储(WRITE_EXTERNAL_STORAGE)的权限。 在想要跟踪的代码逻辑结尾和结尾处别离插桩: 生成的“.trace” 文件会被保留在固定目录下,与“getExternalFilesDir()” 返回的目录雷同,即“/sdcard/Android/data/[YOUR_PACKAGE_NAME]/files” 下。 请留神,如果您的利用在未更改跟踪日志名称的状况下再次调用startMethodTracing(),则会笼罩已保留至设施的现有日志。如果心愿每次运行都保留至不同的日志文件,能够应用如下代码: 如果零碎在您调用 stopMethodTracing()之前达到最大缓冲值,则会进行跟踪并向管理中心发送告诉。开始和进行跟踪的函数在您的整个利用流程内均无效。也就是说,您能够在 Activity的onCreate(Bundle)函数中调用startMethodTracing(),在Activity的 onDestroy()。 ...

August 6, 2021 · 2 min · jiezi

关于性能优化:Python-和-CC-拓展程序如何性能优化看这一篇文就够

作者:王璐璐 | 旷视 MegEngine 架构师一、 背景在MegEngine imperative runtime的晚期开发中,咱们面临着一些的性能优化问题。除了一些已知须要重构的中央(晚期设计时为了开发效率而就义性能的斗争),还存在一些未知的性能问题须要用profiler进行观测和剖析能力发现。MegEngine的imperative runtime是一个由Python和C/C++编写的模块,对于这类程序,各种profiler多到令人目迷五色。在调研各种profiler的过程中,咱们也踩了不少的坑,比方发现两个profiler对同一个程序的profiling后果差别微小,咱们起初狐疑其中一个profiler的准确性有问题,最初发现是两者的观测对象不同,其中一个只profiling程序的CPU time,而另一个profiling wall clock time。尽管一些这样的信息在文档的某些角落里可能找到,但很多使用者可能在踩了坑之后才会留神到。如果一开始能找到一篇介绍各种profiler的特点、劣势、有余和应用场景的文章,咱们可能会节俭不少工夫。 因而本文尝试对这些教训进行总结,心愿可能给首次应用这些工具的读者一些参考。性能优化是一个非常宽泛的话题,它波及CPU、内存、磁盘、网络等方面,本文次要关注Python及C/C++ 拓展程序在CPU上的性能优化,文章次要围绕着上面三个问题开展: Python及C/C++ 拓展程序的常见的优化指标有哪些常见工具的能力范畴和局限是什么,给定一个优化指标咱们应该如何抉择工具各种工具的应用办法和后果的可视化办法除此之外,本文还会介绍一些性能优化中须要理解的基本概念,并在文章开端以MegEngine开发过程中的一个性能优化的理论案例来展现一个优化的流程。 二、 基本概念本节介绍性能优化中的一些根底概念: 2.1 wall clock time, CPU time 和 off-CPU time掂量程序性能最间接的规范就是程序的运行工夫,但仅仅晓得程序的运行工夫很难领导咱们如何把程序优化地更快,咱们想要更进一步地理解这段时间之内到底产生了什么。 Linux零碎上的time命令可能通知咱们一些毛糙的信息,咱们在命令行里输入上面的命令来测量查看某个文件的CRC校验码的运行工夫: time cksum \<some_file\> 以我的电脑(MacBook Pro 2018)为例,失去了以下输入: 8.22s user 1.06s system 96% cpu 9.618 total 这段文字通知了咱们工夫都花在了哪里: 总工夫 9.618suser工夫 8.22ssystem工夫 1.06s其中user和system的含意是user CPU time和system CPU time, 之所以会把CPU的执行工夫分为两个局部,是因为程序在运行时除了执行程序自身代码和一些库的代码,还会调用操作系统提供的函数(即零碎调用,程序运行零碎调用时有更高的权限),因而程序运行时通常会处于两种状态: 用户态和内核态: 内核态指的是CPU在运行零碎调用时的状态,而用户态就是CPU运行非零碎调用(即用户本人的代码或一些库)时的状态。 因而下面提到的user CPU time指的是用户态所破费的工夫,而system CPU time指的是内核态破费的工夫。 咱们发现user CPU time + system CPU time = 8.22s + 1.06s = 9.28s并不等于总工夫9.618s,这是因为这条命令执行的工夫内,程序并不是总是在CPU上执行,还有可能处于睡眠、期待等状态,比方期待文件从磁盘加载到内存等。这段时间既不算在user CPU time也不算在 system CPU time内。咱们把程序在CPU上执行的工夫(即user CPU time + system CPU time)称为CPU time (或on-CPU time), 程序处于睡眠等状态的工夫称为off-CPU time (or blocked time),程序理论运行的工夫称为wall clock time(字面意思是墙上时钟的工夫,也就是真实世界中流逝的工夫),对于一个给定的线程: wall clock time = CPU time + off-CPU time。 ...

July 27, 2021 · 5 min · jiezi

关于性能优化:那些年我们一起做过的性能优化

简介:性能优化是一个体系化、整体性的事件,印刻在我的项目开发环节的各个细节中,也是体现技术深度的大的战场。文章以Quick BI的简单零碎为背景,具体介绍性能优化的思路和伎俩,以及体系化的思考。 始终以来,性能都是技术层面不可避开的话题,尤其在中大型简单我的项目中。犹如汽车整车性能,谋求极速的同时,还要保障舒适性和实用性,而在汽车制作的每个环节、整机整合状况、发动机调校等等,都会最终影响用户体感以及商业达成,如下图性能对收益的影响。性能优化是一个体系化、整体性的事件,印刻在我的项目开发环节的各个细节中,也是体现技术深度的大的战场。上面我将以Quick BI的简单零碎为背景,深扒整个性能优化的思路和伎俩,以及体系化的思考。 如何定位性能问题? 通常来讲,咱们对动画的帧率是比拟敏感的(16ms内),但如果呈现性能问题,咱们的理论体感可能就一个字:“慢”,但这并不能为咱们解决问题提供任何帮忙,由此咱们须要分析这个字背地的整条链路。 上图是浏览器通用的解决流程,联合咱们的场景,我这里形象成以下几个步骤: 能够看出,次要的耗时阶段分为两个: 阶段一:资源包下载(Download Code)阶段二:执行 & 取数(Script Execution & Fetch Data) 如何深刻这两个阶段,咱们个别会用以下几个次要的工具来剖析: Network首先咱们要应用的一个工具是Chrome的Network,它能帮忙咱们初步定位瓶颈所在的环节: 如图示例,在Network中能够高深莫测看到整个页面的:加载工夫(Finish)、加载资源大小、申请数量、每个申请耗时及耗时点、资源优先级等等。下面示例能够很显著看出:整个页面加载的资源很大,靠近了30MB。 Coverage(代码覆盖率)对于简单的前端工程,其工程构建的产物个别会存在冗余甚至未被应用的状况,这些有效加载的代码能够通过Coverage工具来实时剖析: 如上图示例能够看到:整个页面28.3MB,其中19.5MB都未被应用(执行),其中engine-style.css文件的使用率只有不到0.7% 资源大图方才咱们曾经晓得前端资源的利用率非常低,那么具体是哪些有效代码被引入进来了?这时候咱们要借助webpack-bundle-analyzer来剖析整个的构建产物(产物stats能够通过webpack --profile --json=stats.json输入): 如上例,联合咱们以后业务能够看到构建产物的问题: 第一,初始包过大(common.js) 第二,存在多个反复包(momentjs等) 第三,依赖的第三方包体积过大 模块依赖关系有了资源构建大图,咱们也大略晓得了可优化的点,但在一个零碎中,成千盈百的模块个别都是通过相互援用的形式组织在一起,打包工具再通过依赖关系将其构建在一起(比方打成common.js单个文件),想要间接移除掉某个模块代码或依赖可能并非易事,由此咱们可能须要肯定水平抽丝剥茧,借助工具理清零碎中模块的依赖关系,再通过调整依赖或加载形式来作优化: 上图咱们应用到的是webpack官网的analyse工具(其余工具还有:webpack-xray,Madge),只须要将资源大图stats.json上传即可失去整个依赖关系大图 Performance后面讲到的都是和资源加载相干的工具,那么在剖析 “执行 & 取数” 环节咱们应用什么,Chrome提供了十分弱小的工具:Performance: 如上图示例,咱们能够至多发现几个点:主流程串化、长工作、高频工作。 如何优化性能?联合方才提到的剖析工具,方才提到的 “资源包下载”、“执行 & 取数” 两个大的阶段咱们基本上曾经笼罩到,其基本问题和解法也在一直的剖析中逐渐有了思路,这里我将联合咱们这里的场景,给出一些不错的优化思路和成果 大包按需加载要晓得,前端工程构建打包(如webpack)个别是从entry登程,去寻找整棵依赖树(间接依赖),从而依据这棵树产出多个js和css文件bundle或trunk,而一个模块一旦呈现在依赖树中,那么当页面加载entry的时候,同时也会加载该模块。 所以咱们的思路是突破这种间接依赖,针对末端的模块改用异步依赖形式,如下: 将同步的import { Marker } from '@antv/l7'改为异步,这样在构建时,被依赖的Marker会造成一个chunk,仅在此段代码执行时(按需),该thunk才被加载,从而缩小了首屏包的体积。 然而下面计划会存在一个问题,构建会将整个@antv/l7作为一个chunk,而非Marker局部代码,导致该chunk的TreeShaking生效,体积很大。咱们能够应用构建分片形式解决: 如上,先创立Marker的分片文件,使之具备TreeShaking的能力,再在此基础上作异步引入。 下方是咱们优化后的流程比照后果: 这一步,咱们通过按需拆包,异步加载,节俭了资源下载工夫和局部执行工夫 资源预加载其实咱们在分析阶段曾经发现一个“主流程串化”的问题,js的执行是单线程,但浏览器实际上是多线程运行的,这外面就包含异步申请(fetch等),所以咱们进一步的思路是把取数(Fetch Data)与资源下载通过多线程并行。 依照以后现状,接口取数的逻辑个别是耦合在业务逻辑或数据处理逻辑中的,所以解耦(与UI、业务模块等解耦)的步骤必不可少,将纯正的fetch申请(及大量解决逻辑)剥离进去,放到优先级更高的阶段来发动申请。那么放到什么中央呢?咱们晓得,浏览器对资源的解决是有优先级的,失常按如下程序: HTML/CSS/FONTPreload/SCRIPT/XHRImage/Audio/VideoPrefetch要做到资源拉取 和 发动取数并行,就有必要把取数提前到第1优先级(HTML解析结束后立刻执行,而非期待SCRIPT标签资源加载执行过程中发动申请),咱们的流程会变成如下: ...

July 13, 2021 · 1 min · jiezi

关于性能优化:性能工具之locust工具get与post请求

最近在学习 locust 性能工具,发现locust性能工具脚本须要python根底能力写脚本,然而对于性能测试人员来说 python 是根本功夫。 在 locust 中get脚本怎么写,为了不便间接在代码运行调试,采纳敞开web模式,通过参考官网文档本人试验get/post代码,参考代码如:@task(1) def get_7dTest(self): # 定义申请头 header = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"} response = self.client.get("/7d/", headers=header, verify=False) # print("Response status code:", response.status_code) if response.status_code == 200: print("successful") # print("Response text:", response.json()) else: print('failure')post申请写法如下 # 登陆 @task(1)def get_login(self): response = self.client.post("/login", {"userName": "7d", "passWord": "123456"}) print("Response json:", response.json())后果: 后果:[2021-04-24 21:36:49,495] liwen.local/INFO/locust.main: Run time limit set to 1 seconds[2021-04-24 21:36:49,495] liwen.local/INFO/locust.main: Starting Locust 1.4.4[2021-04-24 21:36:49,496] liwen.local/INFO/locust.runners: Spawning 1 users at the rate 1 users/s (0 users already running)...[2021-04-24 21:36:49,496] liwen.local/INFO/locust.runners: All users spawned: webTestDunShan: 1 (1 total running)[2021-04-24 21:36:49,496] liwen.local/INFO/root: Terminal was not a tty. Keyboard input disabled ...

June 21, 2021 · 3 min · jiezi

关于性能优化:性能优化不止是做技术

目录前言建设性能优化体系设定性能要害指标收益评估性能立项结束语题外话前言性能优化简简单单四个字,然而波及了方方面面。做性能优化不止是做技术,还有很多技术之外的事件。咱们常常在知乎、掘金等等平台上看到很多性能优化的帖子。请留神并不是说这些帖子不好,当然他们写的很好,然而做性能优化真的就是只须要晓得有多少种优化策略,有多少种优化技巧吗?这些技巧或者策略短期看来是很有用的,然而长期来看这远远不够。 起源 起源 再次申明文章是作者的痴心妄想,如有意见咱们能够一起探讨,互相学习,互相成长。请轻一点喷 1. 建设性能优化体系作为前端工程师,你懂的,前端性能优化个别比拟琐碎、繁冗、麻烦,那怎么把琐碎、繁冗、麻烦的工作系统化呢?答案也就是你须要建设一套性能优化体系。当然这套优化体系是作者自己学习的性能优化体系,你也能够有本人的性能优化体系,这体系对不同的人、不同的零碎、不同的公司都会存在千差万别。 2. 设定性能要害指标进行性能优化,你就要确定它的指标,而后能力依据指标去采取措施,否则就会像无头苍蝇一样乱撞,没有执行指标。这里列举一些网络上常见的要害指标,先申明指标不是惟一的,他在不同的业务场景可能不一样。段落中列举的指标不是惟一也不是规范,只是为了间隔阐明。 1. 视觉稳定性指标咱们叫它 CLS(Cumulative Layout Shift),也就是布局偏移量,它是指页面从一帧切换到另外一帧时,眼帘中不稳固元素的偏移状况。对于CLS,这里有一篇文章有趣味的同学能够看看。地址 2. 白屏工夫指标什么叫白屏工夫呢?它指的是从输出内容回车(包含刷新、跳转等形式)后,到页面开始呈现第一个字符的工夫。这个过程包含 DNS 查问,建设 TCP 连贯,发送首个HTTP申请(如果应用HTTPS还要染指 TLS 的验证工夫),返回HTML文档,HTML文档 Head 解析结束。它的规范工夫是 300ms。 3. 首屏工夫指标首屏工夫=白屏工夫+渲染工夫。它是指从浏览器输出地址并回车后,到首屏内容渲染结束的工夫。这期间不须要滚动鼠标或者下拉页面,否则有效。首屏工夫咱们常常会听到一个词秒开,然而这个秒开也是有针对性的,如你在挪动端秒开无可非议,但如果你要求一个 PC 治理后盾做到秒开应该也没有什么必要。 4. 交互指标交互方面,有的公司用 FID 指标 (First Input Delay,首次输出提早), 指标必须尽量小于 100ms,如果过长会给人页面卡顿的感觉。还有的公司应用 PSI(Perceptual Speed Index,视觉变化率),衡量标准是小于20%。 5. 相应工夫指标响应工夫是掂量零碎性能的重要指标之一,响应工夫越短,性能越好,个别一个接口的响应工夫是在毫秒级。 数据库响应工夫:数据库操作所耗费的工夫,往往是整个申请链中最耗时的;服务端响应工夫:服务端包含 Nginx 散发的申请所耗费的工夫以及服务端程序执行所耗费的工夫;网络响应工夫:这是网络传输时,网络硬件须要对传输的申请进行解析等操作所耗费的工夫;3. 收益评估收益评估之前我做性能优化的时候,自身没有他在意,然而经验过面试官的毒打之后,我开始意识到这一点。如果仅仅判断性能指标是否优化到位还好,但很多时候,为了让产品同学感觉咱们是为产品服务,而不是又在造轮子,咱们还须要关联产品指标进行收益评估。比方,列表页到详情页的转化率能不能晋升?用户跳出率可不可升高?优化能为公司带来多少收益?这所有都须要做评估。如果你费神费劲做了半个月的优化,最初发现没有任何的价值,不能带来价值和收益,也不会失去认可。兴许你会说我本人失去了技术晋升,我本人很骄傲,然而作为过来人很想说一句,这是资本家的时代。 4. 性能立项性能立项就是通过成立一个项目组,用我的项目化的运作形式来解决性能问题。整个立项流程包含团队成员确定、技术调研发展、我的项目指标制订、获取业务侧反对、我的项目名字选定,需要范畴和优先级确定等过程。不晓得你有没有发现,这个立项不是先定需要范畴和优先级,而后再制订我的项目指标和成立我的项目团队。为什么呢?因为这个性能优化我的项目,是探索性的我的项目需要。探索性我的项目需要,有别于日常的业务我的项目。业务我的项目个别都有明确的我的项目指标和需要批改范畴。比方,晋升首页到列表页的转户率。这个我的项目,需要文档和 UI 图会给出具体模块批改点、款式、内容等,前端开发实现后,产品和 UI 进行验收即可。而探索性我的项目需要,指标不确定,个别须要先选定我的项目团队,做完技术调研,能力确定出我的项目指标。因为探索性我的项目需要中的我的项目指标制订、获取业务侧反对、我的项目立项机会这三点和惯例我的项目不太一样。 结束语如果文章中什么不对或者写的不好的中央,请大家多多斧正,谢谢!码字不易,点个赞加个关注吧! 题外话笔者在「深圳虾皮」,一家口碑还不错的东南亚电商公司,2021大量招人,机会多多!快来退出咱们吧! 当初有想法,还是当前有想法的同学,都能够加我微信[stone---999]!内推你退出咱们的小家庭!

April 28, 2021 · 1 min · jiezi

关于性能优化:你愿意花多少钱为-20-秒的业务优化买单

将来的十年是产业互联网的时代,产业互联网的特点是数字化、线上化、效率化。这意味着各行各业急需数字化转型和效率转型。而在这场转型过程中,企业 OA 零碎扮演着至关重要的角色。 对企业而言,OA 零碎不仅进步了企业的组织管理水平及办公效率,更实现了进步决策效力的目标,使企业竞争力失去晋升。然而,随着 OA 零碎功能模块越来越齐全,越来越臃肿,也让这一效率平台逐步“生效”。 一、OA 零碎的外围,是业务管理中的效力问题OA 零碎的治理最终还须要回归至业务管理的路线上来,毕竟业务才是企业的运作基本。OA 零碎中常见的业务管理包含哪些呢?比方财务报表的制作,凭证的生成;采购部的供货商的治理,洽购单据的输出与保存;业务部的合同治理,客户保护等等。这些大部分都是在表格的模式中实现剖析与决策的,须要要求 OA 零碎将数据完整的保留与共享,并与其余零碎进行数据整合。 但目前企业 OA 零碎中的表格性能,大部分都肩负着非常复杂的业务需要。不仅须要具备着传统 Excel 中的大部分外围性能,包含函数计算、条件格局、图表等等;还须要反对高效的多人协同编辑以及宏大的数据处理需要。 数据量以及表格性能的逐步减少,随之而来的就是计算速度的升高。这不仅会影响工作效率,打断思路的连贯性,也会减少员工或者用户的出错率和对工作的腻烦水平(尤其时在解决反复工作时)。 此外,内存占用的问题,也是 OA 零碎中一项十分重要但容易被人疏忽的性能指标,如果技术选型时未思考内存占用问题,往往会呈现一个 3M 的文件耗费 100 多兆内存空间的状况。如果同时进行蕴含大数据量的 Excel 读操作,很容易造成内存溢出问题。传统企业的技术决策层广泛都会漠视“内存的价值”,然而: 一旦访问量大,内存就会霎时上涨,导致频繁 GC,导致性能降落;内存高也会导致服务器分页,这时性能就会急剧下降;吞吐量降落会导致队列排满,服务器会报 503 等谬误。所以除非企业真的有短缺的估算去降级服务器,不然真的不能疏忽内存的优化。这两个问题的背地,也引出了咱们明天探讨的重点 —— 如何进步 OA 零碎表格模块的数据处理性能 & 表格数据处理产品的技术选型。 二、你违心投入多少老本,为 20 秒的业务优化买单?大部分企业在我的项目的日常开发中遇到表格数据处理需要时,往往会在业务代码中间接引入如 Apache POI 这类的技术解决方案。 Apache POI 作为一款十分弱小的 Office 软件操作包,是 Apache 软件基金会用 Java 编写的收费开源的跨平台 Java API,提供了对 Microsoft Office 格式文件的读写性能,在我的项目中的利用十分宽泛,作为一款开源软件,为开发者提供了极大的便当。 然而,即使 POI 很弱小,但仍存在一些不可漠视的问题。首先是代码绝对比拟繁琐,并且当 Excel 的数据量十分大的时候,POI 的操作逻辑是将整个 Excel 的内容全副读出来放入到内存中,这就导致内存耗费十分重大,一个 3M 的文件甚至须要耗费 100 多兆的内存空间。如果同时进行蕴含大数据量的 Excel 读操作,很容易造成内存溢出问题。 ...

April 23, 2021 · 1 min · jiezi

关于性能优化:细说性能优化的举措

# 性能优化动作 一、思路依据浏览器申请、渲染资源的逻辑来论述。依据用户的感知角度来论述依据咱们目前最常见的开发 部署的模式来论述业界的性能优化规定:ps : 浏览器加载页面的流程,请见: 二、网络层面是否须要 间隔 速度 总量 工具 实际上也有:TCP握手连贯、HTTP申请报文、HTTP回复报文(了解资源加载的性能束缚,包含:TCP连贯限度、TCP慢启动)后续再开展介绍。 2.1 不必传输2.1.1 缓存 dns缓存 cdn缓存 服务器缓存 nginx缓存 客户端缓存<font color="#d35400">CDN缓存 why: </font> CDN(Content Distribute Network,内存散发网络)的实质上依然是一个缓存,而且将数据缓存在离用户最近的中央,是用户以最快速度获取数据,即所谓网络拜访第一跳。CDN个别缓存的是动态资源,如图片,文件,CSS,Script脚本,动态网页等,然而这些文件拜访频率很高,将其缓存在CDN可极大改善网页的关上速度 <font color="#d35400">nginx缓存 why: </font> 代理服务器也能够通过配置缓存性能减速Web申请,当用户第一次拜访动态内容的时候,动态内容就被缓存在反向代理服务器上,这样当其余用户拜访该动态内容的时候,就能够间接从反向代理服务器返回,减速Web申请响应速度,加重服务器负载 <font color="#d35400">客户端缓存:why: </font> CSS,JavaScript,Logo,图标等这些动态资源文件更新的频率都比拟低,而这些文件又简直是每次HTTP申请都须要的,如果将这些文件缓存在浏览器中,能够极好地改善性能。 <font color="#27ae60">客户端缓存:how to do</font> 设置HTTP头中Cache-Control和Expires属性,可设定浏览器缓存,缓存工夫能够是数天甚至是几个月。有时候,动态资源文件变动须要及时利用到客户端浏览器,这种状况能够通过扭转文件名实现,比方个别会在JavaScript前面加上一个版本号,使浏览器刷新批改的文件。 2.1.2 缩小传输次数(有点偏内容层面了) 1. 合并传输 api 合并传输?? 怎么合并没懂 css 合并 ;js合并,图片合并 css sprite等等。 iconfont 2. 按需加载(即暂且不必传输的先不传送) 单页利用下的依照路由的须要加载 不再当前页的 不传送 3. 应用http2.0 3.0 --可一个tcp,多个http传输<font color="#d35400">why: </font> HTTP协定是无状态的应用层协定,意味着每次HTTP申请都须要建设通信链路,进行数据传输,而在服务器端,每个HTTP都须要启动独立的线程去解决,这些通信和服务的开销都很低廉,缩小HTTP申请的数目可无效进步拜访性能。 2.2 传输内容少 见下方内容的局部2.3 传输速度快1. 带宽大2. 服务器相干的性能好,相干反应速度也就快了。3. ★★★prefetch(利用闲暇工夫),可用webpack 的 PreLoadWebpackPlugin插件2.4 缩小传输间隔应用cdn能帮你抉择最优的服务器下载响应你的资源2.5 工具能不能优化http传输协定应用 3.0 2.0 更高的版本总结如下:1. 应用cdn 2. 开启相干缓存3. 减少带宽4. http版本升级5. refetch(利用闲暇工夫)三、资源(内容)层面3.1 有内容,不出错即防止202防止重定向3.2 内容少3.2.1 分批传输 1. 大的内容,分拆一下。 2 应用流,边看便下载3.2.2 去除多余的大小 1. 设计师设计的时候就不大面积应用背景图, 2. api 申请的时候,去除多余的大小,不必要的返回 3. 去除多余的依赖: 控件中的依赖 干掉;webpack 中的sourcemap 2. 去除多余的代码和正文 分号 空格等等 5. 技术选型失当 6. 首页,从单页面 改用多页。 7. 资源按需加载。如hui控件的按需应用 8. 其余: 代码压缩、 9. 缩小cookie大小: 10. 标准代码: 无用的货色,不须要的货色(css js 图片等)删除掉。 3.2.3 自身内容再少 3.2.3.1 压缩一下 1. 首页gzip 2. 设计师本人压缩图片 视频资源 3. 代码压缩: webpack 工具曾经帮咱们做好了 3.2.3.2 内容再缩小 1. 模块化,组件化, 2.按需加载: 第三方库和工具的 按需加载 可用代码拆分(Code-splitting)只传送用户须要的代码。 滚动加载,局部加载 懒加载 3. 业务梳理的时候,首屏设计好。防止大面积图片 4. 应用更小的第三方库 5. 应用新一代图片格式,清晰且体积小 6. 首次应用含糊的 小图,后续再用高清 <font color="#27ae60">缩小cookie大小:how to do</font> ...

March 5, 2021 · 2 min · jiezi

关于性能优化:记录一次快速注册接口的优化

1 新旧版本实现旧版本:PHP语言实现,应用屡次DB查问来生成一个用户名,再DB查问用户表,确保用户名未反复 新版本:PHP语言实现,从Redis间接获取一个可用用户名,注册时候再判断是否未反复 Go版本:Go语言实现,其余统一 这里的优化次要有两点: 1.次要是采纳发号器的思维,预生成可用的账号,而不是每次用的时候才生成2.把判断是否未反复滞后,真正实现注册的那一步才去判断,因为很多用户下载了游戏,未必走到注册那一步,大略只有80%出头的激活注册率 2 压测体现ab压测各情景下均屡次压测,取较两头值的一次数据 2.1 旧版本terence@k8s-master:~$ ab -c 10 -n 50 -p post http://dksdk_api.test/api/v7/user/registeroneab: Could not open POST data file (post): No such file or directoryterence@k8s-master:~$ ab -c 10 -n 50 -p a.txt http://dksdk_api.test/api/v7/user/registeroneThis is ApacheBench, Version 2.3 <$Revision: 1807734 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking dksdk_api.test (be patient).....doneServer Software: nginxServer Hostname: dksdk_api.testServer Port: 80Document Path: /api/v7/user/registeroneDocument Length: 175 bytesConcurrency Level: 10Time taken for tests: 25.667 secondsComplete requests: 50Failed requests: 40 (Connect: 0, Receive: 0, Length: 40, Exceptions: 0)Total transferred: 29886 bytesTotal body sent: 7950HTML transferred: 8636 bytesRequests per second: 1.95 [#/sec] (mean)Time per request: 5133.476 [ms] (mean)Time per request: 513.348 [ms] (mean, across all concurrent requests)Transfer rate: 1.14 [Kbytes/sec] received 0.30 kb/s sent 1.44 kb/s totalConnection Times (ms) min mean[+/-sd] median maxConnect: 0 0 0.2 0 1Processing: 2091 4931 1898.5 4688 10802Waiting: 2091 4931 1898.5 4688 10802Total: 2091 4931 1898.6 4688 10802Percentage of the requests served within a certain time (ms) 50% 4688 66% 6068 75% 6105 80% 6189 90% 7721 95% 8355 98% 10802 99% 10802 100% 10802 (longest request)均匀耗时513ms,其中Lumen框架启动大略30~100ms以内,DB查问视状况是否现实大略500ms左右,非对称加密个位数级别若干毫秒可忽略不计 ...

February 15, 2021 · 4 min · jiezi

关于性能优化:性能优化技巧维表过滤或计算时的关联

在事实表与维表的关联查问时,经常会遇到须要对维表的数据进行过滤或者针对维表做计算的状况,这时能够有两种解决形式: 1、先做关联(如果是内存则能够是预关联),再对关联后的事实表进行过滤。就象在《性能优化技巧:预关联》和《性能优化技巧:外键序号化》中做的那样。 2、先对维表进行过滤,再与事实表做关联。咱们晓得,建设关联时须要维表有索引,过滤之后,原先的索引不再可用了,须要重建索引来产生新的索引。 这两种形式孰优孰劣,不能一概而论,该当和维表与事实表的数据规模比照无关。上面咱们通过试验来探讨一下这些性能优化技巧的成果。 一、 测试环境采纳TPCH规范生成的8张数据表,共50G数据。TPCH数据表的构造网上有很多介绍,这里就不再赘述了。 测试机有两个Intel2670 CPU,主频2.6G,共16核,内存128G,SSD固态硬盘。 为不便看出差距,上面测试都用单线程计算,多核不起作用。 二、 数据表全内存所谓全内存,就是事后把要用到的数据表全都加载到内存里。咱们抉择customer作为维表,共750万条记录;用orders作为事实表,共7500万条记录。 查问时对维表的过滤条件是left(C_NAME,4)!="shen" && C_NATIONKEY>-1 && C_ACCTBAL>bal,求满足这些条件的订单总价。其中前两个条件总是为真(为了减少维表过滤的计算量,以加强试验的比照成果),bal是个参数,用来测试维表过滤后不同数据规模下的成果。 1. 预关联咱们先看预关联后的状况,编写SPL脚本如下: A1中读入维表并创立索引,A2中读入事实表,A3中进行预关联,这些工夫都不计入测试工夫,从A4才开始计时。 2. 重建索引编写SPL脚本如下: A4中customer过滤后再重建索引,A5中进行关联。 3. 复用索引SPL反对在过滤后复用已有的索引,只需将上述A4单元格脚本改为: =customer.select@i(left(C_NAME,4)!="shen" && C_NATIONKEY>-1 && C_ACCTBAL>bal)select加选项@i示意复用customer原来的索引。 4. 外键序号化预加载数据表时加载序号化解决过的组表customer_xh.ctx和orders_xh.ctx。 编写SPL脚本如下: 序号化关联不须要索引,所以A1中不创立索引。A4中用customer:#示意用O_CUSTKEY的值与customer的行号关联。 5. 序号化后对位序列预加载数据表时加载序号化解决过的组表customer_xh.ctx和orders_xh.ctx。 编写SPL脚本如下: 在A4中用customer.(过滤条件) 算出一个与记录数等长的、值为true或false的序列,咱们称之为对位序列;orders表中的O_CUSTKEY曾经序号化解决过,它的值对应于customer的记录行号,所以在A5就能够用A4(O_CUSTKEY)来判断orders中此行数据是否满足过滤条件。 6. 测试后果与剖析试验取得测试后果如下(单位:秒): 这个试验中,维表数据记录750万行,事实表orders数据记录7500万行,是维表的10倍。 在预关联和外键序号化测试中,采纳的是先关联后再过滤的解决形式,简单的过滤计算要在事实表的行上进行,也就是说过滤计算量是间接过滤维表的10倍!所以整个查问的运行工夫是最长的。预关联与外键序号化相比,在查问时,前者会省去关联这一步,所以比后者速度快。 在重建索引和复用索引测试中,采纳的是先对维表过滤后再与事实表关联的解决形式,简单的过滤计算只在维表的行上进行,所以比预关联和外键序号化要快。复用索引与重建索引相比,过滤、关联、求和的计算量雷同,但会在创立索引这一步上节约工夫,所以查问速度也更快。随着维表过滤后的数据规模越来越小,重建索引的工夫也会缩小,整体差距就会变小。 在对位序列测试中,过滤计算也是只在维表的行上进行,计算出对位序列后,只对事实表进行一次过滤,而不必与事实表关联,不必建索引也不必计算hash值,所以速度是最快的! 三、 维表内存、事实表外存这次咱们抉择orders作为维表,共7500万条记录;用lineitem作为事实表,共3亿条记录。 查问时对维表的过滤条件是left(O_ORDERPRIORITY,2)!="9-" && O_ORDERSTATUS!="A" && O_ORDERDATE>date("1990-01-01") && O_TOTALPRICE>price,求满足这些条件的订单总价。其中前三个条件总是为真(为了减少维表过滤的计算量,以加强试验的比照成果),price是个参数,用来测试维表过滤后不同数据规模下的成果。 1. 关联后再过滤咱们先看关联后再过滤的状况,编写SPL脚本如下: A1中读入维表并创立索引,这不计入测试工夫,从A2才开始计时。 因为事实表很大,应用游标读取数据,并与维表关联后再过滤。 2. 重建索引编写SPL脚本如下: A3中orders过滤后再重建索引。 3. 复用索引只需将上述A3单元格脚本改为: ...

January 22, 2021 · 1 min · jiezi

关于性能优化:性能优化技巧外键序号化

一、  问题背景与实用场景在《性能优化技巧:局部预关联》一文中,咱们介绍了将维表内存化并预关联的技术,但事实表与维表关联时,仍需进行hash计算和比对,怎么进步这一步的性能呢?咱们明天再介绍一种优化技巧:外键序号化。 外键序号化的思路是,如果维表的主键是从1开始的自然数(也就是记录所在行号),那么就能够用键值间接按行号定位维表记录,而不再须要计算和比对HASH值了,从而放慢与维表关联的速度,进一步晋升性能。而且,间接用序号定位,还不须要建设索引,占用内存也会小很多。 咱们上面来介绍如何在SPL中应用外键序号化技巧,并应用上文的测试环境,针对同一个查问问题,以序号化后的数据与之前的数据做对照试验,验证序号化的性能晋升成果。 二、  序号化筹备要应用外键序号化技巧,必须要保障维表的主键值正好是序号(记录行号),而理论业务中维表的主键值往往不是这样,所以要先将维表的主键转换成序号。转换的办法如下: 1)新建一个键值-序号对应表,保留维表的键值和天然序号的对应关系; 2)把维表的键值替换为天然序号,失去一个新的维表文件; 3)把事实表里的外键值批改为序号,批改的根据是键值-序号对应表,批改后失去一个新的事实表。 本次试验要用到的三张维表别离是supplier、part与orders,事实表是lineitem,上面别离对它们实现序号化。 1.  supplier序号化实现序号化的SPL脚本如下: A1   从原始数据文件supplier.tbl中读出数据,并用derive函数新减少一列xh,用行号作为字段值 A2   将A1中的S_SUPPKEY、xh两字段输入到集文件supplier_xh_key.btx中,生成键值与序号对应关系表,以备序号化事实表时应用 A3   以xh字段值代替S_SUPPKEY字段,重构supplier序表 A4   创立序号化后的组表文件supplier_xh.ctx A5   将重构后的supplier序表保留到组表文件supplier_xh.ctx中 2.  part序号化实现序号化的SPL脚本如下: 脚本原理与supplier表序号化雷同,生成的键值与序号对应关系表为part_xh_key.btx,序号化后的组表文件叫part_xh.ctx。 3.  orders序号化实现序号化的SPL脚本如下: 脚本原理与supplier表序号化雷同,生成的键值与序号对应关系表为orders_xh_key.btx,序号化后的组表文件叫orders_xh.ctx。 4.  lineitem序号化实现序号化的SPL脚本如下: A1   创立读入lineitem原始数据的游标 A2/A3/A4   别离读入orders、part、supplier键值与序号对应关系表 A5   用L_ORDERKEY与orders对应关系表关联,用L_PARTKEY与part对应关系表关联,用L_SUPPKEY与supplier对应关系表关联 A6   用关联后的序号值替换键值生成新的游标 A7   创立序号化后的组表文件lineitem_xh.ctx A8   将序号化后的游标数据写入组表lineitem_xh.ctx 三、  序号化测试1.   原始数据测试维表预加载SPL脚本如下: 加载维表并建索引。 编写SPL测试脚本如下: 先运行维表预加载脚本,再运行测试脚本,失去测试脚本运行工夫为450秒。 2.  序号化数据测试维表预加载SPL脚本如下: 加载的是序号化后的维表,不须要建设索引。 编写SPL测试脚本如下: 留神:A2中关联时应用“:#”与维表关联,示意用事实表中的键值与维表的行号进行关联,如果键值是7,则间接与维表的第7行关联。 先运行维表预加载脚本,再运行测试脚本,失去测试脚本运行工夫为269秒。 3.  剖析与论断在下面两组对照试验中,序号化后的数据与序号化前相比,维表的记录数、字段数完全相同,事实表的记录数与字段数也完全相同,仅有相干的键值换成了序号。查问过程相比,过滤条件完全相同,过滤后的参加计算的数据完全相同,也就是说过滤与分组求和所用的工夫完全相同,所不同的仅有关联的形式(行号关联、键值的hash值比对关联),而运行工夫缩小了450-269=181秒,可见,外键序号化对性能晋升成果非常显著。 四、  进一步阐明序号化的字段必须是维表的主键,但不限主键字段的数据类型,整数、字符串、日期、工夫等等都能够序号化。对于多主键维表,能够新增一个序号字段,建设多个键值与序号的对应关系表,并依此对事实表进行序号化。 一般来说,外键序号化技巧能够很不便地实用于历史数据的查问,只需对历史数据进行一次序号化就能够应用了,键值与序号对应关系表也无须再保留。 但外键序号化技巧同样实用于有新增数据的查问,只是会多减少些步骤。 1.  维表与事实表均有新增数据1)先获得维表新减少的记录,追加键值与序号对应关系表; 2)再把新增记录追加到序号化后的维表,追加时根据键值与序号对应关系表; 3)再把事实表新减少的记录追加到序号化后的事实表,追加时根据键值与序号对应关系表; 2.  仅事实表有新增数据在维表数据放弃不变的状况下,仅需进行上述第3)步即可。 解决好新增数据当前,就能够应用外键序号化关联查问技巧了。

January 12, 2021 · 1 min · jiezi

关于性能优化:性能优化技巧部分预关联

一、  问题背景与实用场景在《性能优化技巧:预关联》中,咱们测试了将数据表当时全副加载进内存并做好关联后的查问性能优化问题,但如果内存不够大,不能将维表和事实表全副装入,那怎么办呢?此时,能够将维表事后装入内存,建好索引,实现维表局部的预关联,省去一半hash计算。 咱们上面再来测试一下这种场景,这次用数据量最大、内存装不下的lineitem表做测试,在SPL局部预关联中,将其它7张表事后装进内存,而lineitem在查问时才实时读入。 二、  SQL测试仍然用 Oracle 数据库作为 SQL 测试的代表,从lineitem表里查问每年整机订单的总收入。 1.  两表关联查问的SQL语句如下: select        l_year,        sum(volume) as revenue from        (               select                      extract(year from l_shipdate) as l_year,                      (l_extendedprice * (1 - l_discount) ) as volume               from                      lineitem,                      part               where                      p_partkey = l_partkey                      and length(p_type)>2        ) shipping group by        l_year order by        l_year; 2.   六表关联查问的SQL语句如下: select        l_year,        sum(volume) as revenue ...

January 12, 2021 · 1 min · jiezi

关于性能优化:性能优化技巧预关联

一、  问题背景与实用场景SQL中JOIN的性能是个老大难问题,特地是关联表较多时,计算性能会急剧下降。 SQL实现JOIN个别是采纳HASH分堆的方法,即先计算关联键的HASH值,再将雷同HASH值的记录放到一起再做遍历比照。每一个JOIN都要做一轮这样的运算。 如果数据量绝对于内存并不是很大,能够当时全副加载到内存中,那么能够利用内存指针的机制,当时把关联关系建设好。这样做运算时就不用再做HASH与比照运算了。具体来说,就是在数据加载时一次性把HASH和比照运算做完,用指针形式保留关联后果,而后每次运算能够间接援用到关联记录,从而进步运算的性能。 可怜的是,SQL没有指针数据类型,无奈实现这个优化逻辑,即便数据量能够在内存中装下,也很难利用预关联技巧提速,基于SQL的内存数据库也大都有这个毛病。而SPL有指针数据类型,就能够实现这种机制。 咱们上面来测试一下SQL实现单表计算和多表关联计算的差距,再用SPL利用预关联技巧同样做一遍,看一下两者的差距比照。 二、  测试环境采纳TPCH规范生成的8张数据表,共50G数据(要小到能放进内存)。TPCH数据表的构造网上有很多介绍,这里就不再赘述了。 测试机有两个Intel2670 CPU,主频2.6G,共16核,内存128G,SSD固态硬盘。 因为 lineitem 表数据量太大,这台服务器内存不足以将它装入,所以创立了一张表构造与它一样的表 orderdetail, 将数据量缩小到内存能装下,上面就用这张表来做测试。 为不便看出差距,上面测试都用单线程计算,多核并不起作用。 三、  SQL测试这里用 Oracle 数据库作为 SQL 测试的代表,从orderdetail表里查问每年整机订单的总收入。 1.  两表关联查问的SQL语句如下: select        l_year,        sum(volume) as revenue from        (               select                      extract(year from l_shipdate) as l_year,                      (l_extendedprice * (1 - l_discount) ) as volume               from                      orderdetail,                      part               where                      p_partkey = l_partkey                      and length(p_type)>2        ) shipping group by        l_year ...

January 12, 2021 · 1 min · jiezi

关于性能优化:性能优化技巧TopN

TopN是常见的运算,用SQL写进去是这样(以Oracle为例):       select from (select from T order by x desc) where rownum<=N这个SQL的运算逻辑从其语句上看,要先做排序(Order by),而后再取出前N条。 咱们晓得,排序是个十分慢的动作,复杂度很高(n*logn),如果波及数据量大到内存放不下,那还须要进行内外存数据交换,性能还会急剧下降。 而事实上,要计算TopN,咱们能设计出不须要全排序的算法,只有放弃一个大小为N的小汇合,对数据集遍历一次,将遍历过的数据的前N名保留在这个小汇合中,遍历到新一条数据,如果比以后的第N名还大,则插入进去并丢掉当初的第N名,如果比以后的第N名要小,则不做动作。 这样计算的复杂度要低很多(n*logN,n是总数据条数),而且个别N都不大,能够在内存中放下,无论数据量有多大,都不会波及内外存替换问题。 然而,SQL无奈形容下面这个计算过程,这时,咱们只能寄希望于数据库引擎是不是能本人优化。应用SPL就容易形容下面这个计算过程,从而实现高性能计算。 咱们来测试一下看Oracle是不是会做这个优化,即用Oracle实现TopN后和SPL做同样运算相比。因为SPL能应用优化算法,如果Oracle的计算工夫和SPL差不多,则阐明它做了优化,如果差得很远,则可能是做了全排序。 一、      数据筹备和环境用SPL脚本生成数据文件,数据共两列,第一列id是小于20亿的随机整数,第二列amount是不大于1千万的随机实数。数据记录为80亿行,生成的原始文本文件大小为169G。利用数据库提供的数据导入工具将此文件数据导入到Oracle的数据表topn中,同时也用此文件数据生成SPL组表文件topn.ctx。 在一台Intel服务器上实现测试,2个Intel3014 CPU,主频1.7G,共12核,内存64G。数据库表数据及SPL组表文件均存储在同一块SSD硬盘上。 咱们刻意将数据量设计得比内存大,这样如果进行排序则会有内外存替换动作,性能降落会十分大,容易被观测到。 二、      惯例TopN取出topn表中amount最大的前100条。 1.        Oracle测试查问用的SQL语句是: select * from ( select  /+ parallel(4) / from topn order by amount desc) where rownum<=100; 阐明:/+ parallel(4) / 是Oracle的并行查问语法,其中4是并行数。 2.        SPL测试编写SPL脚本执行测试: 与SQL不同,SPL把TopN看成是一种聚合运算,和sum/count这类运算一样,不同的只是TopN将返回一个汇合,而sum/count返回的是单值。但它们的计算逻辑是一样的,都只须要对原数据集遍历一次,并且不波及全排序。 A4格中的groups(;top(100;-amount)就是对选集做TopN聚合运算,计算出前100名。 3.        论断与剖析惯例TopN测试工夫见下表: 测试后果(工夫单位:秒) 测试表明,Oracle比SPL还要更快一点,而SPL没有做全排序,这阐明Oracle在这种状况会主动优化。 Oracle比SPL快也能够了解,因为Oracle是用C++开发的,而目前版本的SPL是用java开发的。C++比java计算更快是失常的,而且这次测试读取了全副的两列数据,且数据随机无序,很难压缩,所以组表的列式存储也没有劣势。 三、      减少复杂度对于最根本的TopN,Oracle很聪慧,即便写成了子查问也会优化。咱们上面减少问题的难度,改成分组后在每一组中做TopN。 具体运算设计为:依照id字段最初一位数字值进行分组,而后查问出每组中amount最大的前100条记录。id是个整数,这样也就只有10个分组,分组自身的计算量并不大,不过要对分组数据做TopN,整体计算复杂度略高了一些。如果没有全排序,总体运算工夫该当比方才的状况多,但还在同一数量级范畴内。 1.        Oracle测试查问用的SQL语句是: select * from ( select  /+ parallel(2) /        mod(id,10) as gid,amount, ...

January 12, 2021 · 1 min · jiezi

关于性能优化:性能优化技巧遍历复用提速多次分组

咱们晓得,大数据运算性能的瓶颈经常是在外存(也就是硬盘)IO上,因为外存拜访性能要比内存低一两个数量级。因而,做性能优化时,缩小硬盘的访问量有时要比缩小CPU计算量更为重要。同一个工作,如果能应用硬盘访问量更少的算法,即便CPU计算量不变甚至略多一点,也会取得更好的性能。 分组汇总须要对数据集进行遍历。同一个数据集可能会按不同维度进行分组,这样原则上就要遍历屡次,大数据时就会波及多遍硬盘拜访。然而,如果咱们能在一次遍历过程中计算出多个维度的分组后果,那就会缩小很多硬盘访问量。 惋惜,SQL无奈写出这样的运算(在遍历中返回多个分组后果),只能遍历屡次,或者寄希望于数据库引擎是否能优化。而SPL则反对这种遍历复用的语法,能够一次遍历计算出多个分组后果,从而进步性能。 上面咱们做一下测试,以Oracle为例看数据库是否会对屡次遍历的计算进行优化,以及在SPL中采纳遍历复用算法对性能的影响。 一、      数据筹备和环境SPL脚本生成数据文件,数据共两列,第一列id是小于20亿的随机整数,第二列amount是不大于1千万的随机实数。数据记录为80亿行,生成的原始文本文件大小为169G。利用数据库提供的数据导入工具将此文件数据导入到Oracle的数据表topn中,同时也用此文件数据生成SPL组表文件topn.ctx。 在一台Intel服务器上实现测试,2个Intel3014 CPU,主频1.7G,共12核,内存64G。数据库表数据及SPL组表文件均存储在同一块SSD硬盘上。 这里刻意把数据量造得比内存大,以保障操作系统不可能把这些数据都缓存进内存,理论运算时肯定会读取硬盘。 二、      Oracle测试测试分成三种状况:单分组单倍计算量、单分组双倍计算量、双分组双倍计算量。 1.        单分组单倍计算量select  /+ parallel(12) / mod(id,100) Aid,max(amount) Amax from topn group by mod(id,100) 2.        单分组双倍计算量select  /+ parallel(12) / mod(id,100)+floor(id/20000000) Aid, max(amount) Amax, min(amount) Amin from topn group by mod(id,100)+floor(id/20000000); 计算式多了一倍,相当于计算量大了一倍。 3.        双分组双倍计算量select  /+ parallel(12) /  * from (select mod(id,100) Aid,max(amount) Amax from topn group by mod(id,100) ) A join( select floor(id/20000000) Bid,min(amount) Bmin from topn group by floor(id/20000000) )  Bon A.Aid=B.Bid; 这里的计算量大体与2雷同,但有两个分组,咱们将察看数据库是否会进行两次遍历。最初的JOIN运算只波及100行数据,工夫能够忽略不计。 三、      SPL测试咱们把Oracle做的测试用SPL再做一遍。 1.        单分组单倍计算量编写SPL脚本执行测试: 2.        单分组双倍计算量编写SPL脚本执行测试: 3.        双分组双倍计算量编写SPL脚本执行测试: 这里采纳了SPL特有的遍历复用语法,在A3定义了游标,A4/B4和A5/B5中定义了两套针对这个游标的计算,示意会在一次游标遍历过程同时计算这两个后果。 四、      剖析与论断三种状况的测试用时如下表: 测试后果(工夫单位:秒) 从Oracle的测试后果上看,双分组双倍计算量比单分组双倍计算量慢了近200秒,这不是一个能够疏忽的工夫了,因为两者的计算量简直雷同,这多进去的工夫预计就是多做一次遍历的工夫了。这阐明数据库不会主动做遍历复用的优化,在双分组时会将数据表遍历两次,后果多做一次分组简直会多出一倍的工夫。 而SPL采纳了遍历复用的机制,三个测试的计算工夫相差很小,多做一次分组并不会多一次遍历,只是多了一些复用管制的逻辑,不会变慢多少。 阐明一下,筹备数据时把Oracle的amount字段类型设置成decimal了,所以计算速度比较慢;而SPL组表中用的是double类型,所以要快得多。但这个测试不是比照Oracle和SPL的计算性能,这些不同并不影响下面的论断。

January 12, 2021 · 1 min · jiezi

关于性能优化:性能优化各项指标计算方式

背景掂量页面性能的形式。 参数阐明具体文字说明: navigationStart 加载起始工夫redirectStart 重定向开始工夫(如果产生了HTTP重定向,每次重定向都和以后文档同域的话,就返回开始重定向的fetchStart的值。其余状况,则返回0)redirectEnd 重定向完结工夫(如果产生了HTTP重定向,每次重定向都和以后文档同域的话,就返回最初一次重定向承受完数据的工夫。其余状况则返回0)fetchStart 浏览器发动资源申请时,如果有缓存,则返回读取缓存的开始工夫domainLookupStart 查问DNS的开始工夫。如果申请没有发动DNS申请,如keep-alive,缓存等,则返回fetchStartdomainLookupEnd 查问DNS的完结工夫。如果没有发动DNS申请,同上connectStart 开始建设TCP申请的工夫。如果申请是keep-alive,缓存等,则返回domainLookupEnd(secureConnectionStart) 如果在进行TLS或SSL,则返回握手工夫connectEnd 实现TCP链接的工夫。如果是keep-alive,缓存等,同connectStartrequestStart 发动申请的工夫responseStart 服务器开始响应的工夫domLoading 从图中看是开始渲染dom的工夫,具体未知domInteractive 未知domContentLoadedEventStart 开始触发DomContentLoadedEvent事件的工夫domContentLoadedEventEnd DomContentLoadedEvent事件完结的工夫domComplete 从图中看是dom渲染实现工夫,具体未知loadEventStart 触发load的工夫,如没有则返回0loadEventEnd load事件执行完的工夫,如没有则返回0unloadEventStart unload事件触发的工夫unloadEventEnd unload事件执行完的工夫应用DNS解析工夫: domainLookupEnd - domainLookupStartTCP建设连接时间: connectEnd - connectStart白屏工夫: responseStart - navigationStartdom渲染实现工夫: domContentLoadedEventEnd - navigationStart页面onload工夫: loadEventEnd - navigationStart 后果var timing = performance.timing;var times = { redirect:timing.redirectEnd - timing.redirectStart, lookupDomain:timing.domainLookupEnd - timing.domainLookupStart, connect:timing.connectEnd - timing.connectStart, request:timing.responseEnd - timing.requestStart};

January 5, 2021 · 1 min · jiezi

关于性能优化:mycatmysqltidb冷热数据分离优化查询效率

mycat简介Mycat Server相当于一个超级分布式数据库,反对1000亿数据TiDB简介:PingCAP设计的开源分布式数据库业务革新前逻辑案例起源:中移物联网团体三费稽核零碎业务革新后逻辑案例起源:中移物联网团体三费稽核零碎

December 30, 2020 · 1 min · jiezi

关于性能优化:排查压测问题引发的系统性能调优过程

前言:明天测试部门的小梦找到我,冤屈巴巴的说我写的接口有问题,因为她对这个接口进行压力测试时,发现零碎的吞吐量始终上不去,并且 应用服务器 (部署接口我的项目的服务器) 的CPU、内存等资源的使用率也始终很低,导致始终无奈测试出这个接口的压力峰值。 听小梦说完后,本人心想接口都测试了好几遍了,接口代码 相对不可能有问题的,再说了,有问题也不能抵赖呀,看来得往别的中央上扯扯呀;而后我说道,接口应该是没问题的,可能是我的项目环境部署时有些参数没进行调优吧,例如:连接数大小设置、JVM参数设置、数据库参数优化等; 而后我接着说道,我的项目是谁给你部署配置的呀,小梦说是小王部署的,而后明天小王也没来下班;我说道,小王没来下班呀,没事,让我来,我这bug绝缘体质,任何问题遇到我都会退避三舍的。 下面的情景,我置信大家都可能会遇到过的;接下来咱们就通过这次排查压测问题来聊聊一个 单体零碎 的性能优化应该思考哪些点,以及对这些点该怎么进行调优 。 本文主线如下图: 我的项目部署环境:在进行这次压测问题排查前,先通过下图理解下 接口我的项目的状况、我的项目部署的环境、JMeter测试脚本 的配置状况; 上图中的接口我的项目、Redis、MySql 都是单机装置部署的 。留神: 再进行下文之前,咱们还须要记住一个前提:本我的项目中的接口代码是不存在问题的,并且数据库查问SQL都是最优的,都是走索引查问的,本次压力测试问题不是因为代码导致的,而是因为各种参数未调优造成的;代码调优和SQL调优在编码阶段就曾经实现了。 简略性能调优的点:在上文中的我的项目部署状况和测试脚本的配置状况下进行压力测试时,就呈现了小梦说的零碎吞吐量上不去,以及应用服务器(部署接口我的项目的服务器)的 CPU 等资源使用率都很低的状况;查看 JMeter 测试时零碎的吞吐量如下图: 查看应用服务器(部署接口我的项目的服务器)的CPU使用率很低: 依照测试脚本的50个并发以及接口中含有计算密集型操作(加解密和验签)的状况,CPU是不应该这么低的;哎!什么鬼嘛? 别急,上面咱们就开展具体的排查过程,并在排查过程中逐渐理解各个调优的点;排查过程就是依照文章结尾中的 本文主线 图片中 简略性能调优的点 开展的 。 排查Tomcat连接器参数配置:Tomcat 连接器参数配置只须要思考以下几个方面:Connector应用哪种 protocol 协定 HTTP/1.1:默认值,应用的协定与Tomcat版本无关倡议应用 NIO2:org.apache.coyote.http11.Http11Nio2Protocol除了NIO2协定外,还有 BIO、NIO、APR 协定,能够自行去查阅材料;acceptCount:期待队列的长度;当期待队列中连贯的个数达到acceptCount时,阐明队列已满,再进来的申请一律被回绝;默认值是100。maxConnections:Tomcat 在任意时刻接管和解决的最大连接数; 当连接数达到最大值maxConnections后,Tomcat会持续接管连贯,直到accept期待队列填满。如果最大连接数设置为-1,则示意禁用maxconnections性能,示意不限度tomcat容器的连接数;最大连接数默认值与连接器应用的 protocol 协定无关: NIO的默认值是10000;APR/native的默认值是8192;BIO的默认值为maxThreads(如果配置了Executor,则默认值是Executor的maxThreads);maxThreads:每一次HTTP申请达到 Tomcat,都会创立一个线程来解决该申请,那么最大线程数决定了Tomcat 能够同时解决多少个申请。 maxThreads 默认200;倡议:maxThreads应该设置大些,以便可能充分利用CPU;当然,也不是越大越好,如果maxThreads过大,那么CPU会破费大量的工夫用于线程的上下文切换,整体效率可能会升高;这须要依据本人我的项目的状况和服务器硬件配置状况配置适合的值即可;上面就是本次压测时配置的Tomcat连接器参数: <Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" maxThreads="1000" maxConnections="2000" acceptCount="1000" connectionTimeout="20000" redirectPort="8443" enableLookups="false" maxPostSize="10485760" compression="on" disableUploadTimeout="true" compressionMinSize="2048" acceptorThreadCount="2" compressableMimeType="text/html,text/xml,text/css,text/javascript" URIEncoding="utf-8" />下面连接器中配置参数:的 连接器应用的 protocol 协定是 NIO2最大线程数 maxThreads="1000"最大连接数 maxConnections="2000"期待队列大小 acceptCount="1000"依据下面连接器配置参数,和压测脚本配置的并发申请才50个,确定压测问题应该不是因为连接器参数造成的。 其实在查看Tomcat配置文件 server.xml 中的连接器参数前,能够应用上面这个命令先间接统计出 JMeter与Tomcat建设的Http连接数: 留神 8080 指的是 Tomcat 端口号,应用前改成你的Tomcat配置的端口 ...

December 14, 2020 · 2 min · jiezi

关于性能优化:聊一聊前端性能优化-CRP

什么是 CRP?CRP又称要害渲染门路,援用MDN对它的解释: 要害渲染门路是指浏览器通过把 HTML、CSS 和 JavaScript 转化成屏幕上的像素的步骤程序。优化要害渲染门路能够进步渲染性能。要害渲染门路蕴含了 Document Object Model (DOM),CSS Object Model (CSSOM),渲染树和布局。优化要害渲染门路能够晋升首屏渲染工夫。了解和优化要害渲染门路对于确保回流和重绘能够每秒 60 帧、确保高性能的用户交互和防止无意义渲染至关重要。 如何联合CRP进行性能优化?我想对于性能优化,大家都不生疏,无论是平时的工作还是面试,是一个陈词滥调的话题。 如果单纯针对一些点去泛泛而谈,我想是不太谨严的。 明天咱们联合一道十分经典的面试题:从输出URL到页面展现,这两头产生了什么?来从其中的某些环节,来深刻谈谈前端性能优化 CRP。 从输出 URL 到页面展现,这两头产生了什么?这道题的经典水平想必不必我多说,这里我用一张图梳理了它的大抵流程:这个过程能够大抵形容为如下: 1、URI 解析 2、DNS 解析(DNS 服务器) 3、TCP 三次握手(建设客户端和服务器端的连贯通道) 4、发送 HTTP 申请 5、服务器解决和响应 6、TCP 四次挥手(敞开客户端和服务器端的连贯) 7、浏览器解析和渲染 8、页面加载实现 本文我会从浏览器渲染过程、缓存、DNS 优化几方面进行性能优化的阐明。 浏览器渲染过程构建 DOM 树构建DOM树的大抵流程梳理为下图: 咱们以上面这段代码为例进行剖析: <!DOCTYPE html><html> <head> <meta name="viewport" content="width=device-width,initial-scale=1" /> <link href="style.css" rel="stylesheet" /> <title>构建DOM树</title> </head> <body> <p>森林</p> <div>之晨</div> </body></html>首先浏览器从磁盘或网络中读取 HTML 原始字节,并依据文件的指定编码将它们转成字符。 而后通过分词器将字节流转换为 Token,在Token(也就是令牌)生成的同时,另一个流程会同时耗费这些令牌并转换成 HTML head 这些节点对象,起始和完结令牌表明了节点之间的关系。 当所有的令牌耗费完当前就转换成了DOM(文档对象模型)。 ...

November 24, 2020 · 2 min · jiezi

关于性能优化:如何将MySQL查询优化到极致

写在后面MySQL数据库在互联网行业应用的比拟多,有些小伙伴可能会认为MySQL数据库比拟小,存储不了很多的数据。其实,这些小伙伴是真的不理解MySQL。MySQL的小不是说应用MySQL存储的数据少,而是说其体积小,比拟轻量。应用MySQL齐全能够存储千亿级别的数据,这个我会在前面的文章中来给小伙伴们分享如何应用MySQL存储千亿级别以上的数据。或者小伙伴们能够提前预约我的新书《MySQL技术大全:开发、优化与运维实战》。好了,说了这么多,明天给大家分享下如何以最高的效率从MySQL中随机查问一条记录!办法一这是最原始最直观的语法,如下: SELECT * FROM foo ORDER BY RAND() LIMIT 1当数据表中数据量较小时,此办法可行。但当数据量达到肯定水平,比方100万数据或以上,就有很大的性能问题。如果你通过EXPLAIN来剖析这个 语句,会发现尽管MySQL通过建设一张长期表来排序,但因为ORDER BY和LIMIT自身的个性,在排序未实现之前,咱们还是无奈通过LIMIT来获取须要的记录。亦即,你的记录有多少条,就必须首先对这些数据进行排序。 办法二看来对于大数据量的随机数据抽取,性能的症结出在ORDER BY上,那么如何防止?办法二提供了一个计划。 首先,获取数据表的所有记录数: SELECT count(*) AS num_rows FROM foo而后,通过对应的后台程序记录下此记录总数(假设为num_rows)。 而后执行: SELECT * FROM foo LIMIT [0到num_rows之间的一个随机数],1下面这个随机数的取得能够通过后台程序来实现。此办法的前提是表的ID是间断的或者自增长的。 这个办法曾经胜利防止了ORDER BY的产生。 办法三有没有可能不必ORDER BY,用一个SQL语句实现办法二?能够,那就是用JOIN。 SELECT * FROM Bar B JOIN (SELECT CEIL(MAX(ID)*RAND()) AS ID FROM Bar) AS m ON B.ID >= m.ID LIMIT 1;此办法实现了咱们的目标,同时,在数据量大的状况下,也防止了ORDER BY所造成的所有记录的排序过程,因为通过JOIN外面的SELECT语句实际上只执行了一次,而不是N次(N等于办法二中的num_rows)。而且, 咱们能够在筛选语句上加上“大于”符号,还能够防止因为ID好不间断所产生的记录为空的景象。 在MySQL中查问5条不反复的数据,应用以下: SELECT * FROM `table` ORDER BY RAND() LIMIT 5就能够了。然而真正测试一下才发现这样效率非常低。一个15万余条的库,查问5条数据,竟然要8秒以上 搜寻Google,网上基本上都是查问max(id) * rand()来随机获取数据。 ...

November 4, 2020 · 2 min · jiezi

关于性能优化:JMH大厂是如何使用JMH进行Java代码性能测试的必须掌握

Java 性能测试难题当初的 JVM 曾经越来越为智能,它能够在编译阶段、加载阶段、运行阶段对代码进行优化。比方你写了一段不怎么聪慧的代码,到了 JVM 这里,它发现几处能够优化的中央,就棘手帮你优化了一把。这对程序的运行诚然美好,却让开发者不能精确理解程序的运行状况。在须要进行性能测试时,如果不晓得 JVM 优化细节,可能会导致你的测试后果差之毫厘,失之千里,同样的,Java 诞生之初就有一次编译、随处运行的口号,JVM 提供了底层反对,也提供了内存管理机制,这些机制都会对咱们的性能测试后果造成不可预测的影响。 long start = System.currentTimeMillis();// ....long end = System.currentTimeMillis();System.out.println(end - start);下面可能就是你最常见的性能测试了,这样的测试后果真的精确吗?答案是否定的,它有上面几个问题。 工夫精度问题,自身获取到的工夫戳就是存在误差的,它和操作系统无关。JVM 在运行时会进行代码预热,说白了就是越跑越快。因为类须要装载、须要筹备操作。JVM 会在各个阶段都有可能对你的代码进行优化解决。资源回收的不确定性,可能运行很快,回收很慢。带着这些问题,忽然发现进行一次严格的基准测试的难度大大增加。那么如何能力进行一次严格的基准测试呢? JMH 介绍那么如何对 Java 程序进行一次精准的性能测试呢?难道须要把握很多 JVM 优化细节吗?难道要钻研如何防止,并进行正确编码能力进行严格的性能测试吗?显然不是,如果是这样的话,未免过于艰难了,好在有一款一款官网的微基准测试工具 - JMH. JMH 的全名是 Java Microbenchmark Harness,它是由 Java 虚拟机团队开发的一款用于 Java 微基准测试工具。用本人开发的工具测试本人开发的另一款工具,以子之矛,攻子之盾果然手到擒来,如臂使指。应用 JMH 能够让你不便疾速的进行一次严格的代码基准测试,并且有多种测试模式,多种测试维度可供选择;而且应用简略、减少注解便可启动测试。 JMH 应用JMH 的应用首先引入 maven 所需依赖,以后最新版 为 1.23 版本。 <!--jmh 基准测试 --><dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-core</artifactId> <version>1.23</version></dependency><dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>1.23</version> <scope>provided</scope></dependency>疾速测试上面应用注解的形式指定测试参数,通过一个例子展现 JMH 基准测试的具体用法,先看一次运行成果,而后再理解每个注解的具体含意。 这个例子是应用 JMH 测试,应用加号拼接字符串和应用 StringBuilder 的 append 办法拼接字符串时的速度如何,每次拼接1000个数字进行平均速度比拟。 ...

August 25, 2020 · 4 min · jiezi

关于性能优化:性能优化微服务并发编程开源框架分布式面试你还缺什么

前关注我的敌人应该晓得,我有一个习惯, 每年在面试淡季,我都会去进行一次面试,除了查看本人的业务水平怎么样之外,还想碰碰运气,说不定就有比拟好的工作岗位能遇到呢,对吧? 然而,往年在面试的过程中以及和身边的敌人在交换的时候,失去一个通用的点:传统的行业需要还在问,然而问的难度加深,新型的技术需要反而询问更多,尤其是实际操作教训的询问 然而说实话,不是说在座的所有人啊,我感觉大部分人很多技术会或者说在本人的pc端玩过,然而这跟实在生产环境还有一些区别的,哪怕有些敌人会用做压测,然而性能这个玩意,我想大家都懂 这不,闲来无事,我打开了我落灰的百度网盘,在其中找找看有没有比拟好的材料,没想到,还真让我发现了一份文档,也是一份面试题 内容涵盖:性能优化、微服务、并发编程、开源框架、分布式 目录 一、性能优化专栏作为一个程序员,性能优化是常有的事件,不论是桌面利用还是web利用,不论是前端还是后端,不论是单点利用还是分布式系统。而且,当初随着业务模块的一直减少以及数据流量的暴发,所以性能优化成为第一重要的面试重点 二、微服务架构面试专栏微服务是一种架构格调,一个大型简单软件应用由一个或多个微服务组成。零碎中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于实现一件工作并很好地实现该工作。在所有状况下,每个工作代表着一个小的业务能力。这也解决了传统的整体式架构开发,随着新需要的一直减少,企业更新和修复大型整体式利用变得越来越艰难的问题 三、并发编程高级面试专栏并发编程的目标是为了进步程序的执行速度.然而并不意味着启动更多的线程会达到更好的并发成果,并发编程还会引起死锁 , 上下文频繁切换 , 线程不平安等问题.所以,更好的实现高并发与多线程也成为面试重点之一 四、开源框架面试题专栏开源框架我想大家都晓得,spring、mybatis、jvm等技术,在平时是与程序员非亲非故的,也是最罕用的技术,所以,为了可能更好的开发,企业对于这些技术的底层源码问的会绝对较多,也是为了检测你的技术掌握情况 五、分布式面试专栏分布式我想不须要说太多吧,大家应该都分明,无论是业务的增大,还是企业流量的压力,分布式都是一个很重要的解决的计划,各种集群层出不穷,这个时候,分布式的用武之地就会失去酣畅淋漓的展示  关注公众号:Java架构师联盟,每日更新技术好文,须要这份文档,增加小助手:msbxq2020收费获取 局部材料曾经上传到我的git仓库中:有须要的能够下载 https://gitee.com/biwangsheng/mxq

August 3, 2020 · 1 min · jiezi

关于性能优化:技术分享-使用-systemd-修改资源隔离配置

作者:晏泽爱可生售后团队成员,次要负责公司数据库运维产品问题诊断;致力在数据库和 IT 畛域里摸爬滚打中。本文起源:原创投稿*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。本文关键字:Linux、systemd、资源隔离一,批改systemd unit file为了给程序配置资源隔离,通常咱们会到cgroup层级树下的控制器里,创立或者批改控制组文件。在Linux7中,如果为程序配置了systemd服务,除了间接批改控制组文件之外,还能够通过systemd相干命令对程序的资源隔离配置进行批改。 1.1 批改办法有两种办法能够对配置了systemd的程序进行资源隔离: 命令行批改:通过执行systemctl set-property命令实现,模式为systemctl set-property name parameter=value;批改默认即时失效手工批改文件:间接编辑程序的systemd unit file文件,实现之后需手工执行systemctl daemon-reload更新配置,并重启服务systemctl restart name.servicesystemd unit file里反对的资源隔离配置项,如常见的: CPUQuota=value该参数示意服务能够获取的最大CPU工夫,value为百分数模式,高于100%示意可应用1核以上的CPU。与cgroup cpu控制器cpu.cfs_quota_us配置项对应。 MemoryLimit=value该参数示意服务能够应用的最大内存量,value能够应用K, M, G, T等后缀示意值的大小。与cgroup memory控制器memory.limit_in_bytes 配置项对应。 残缺的配置项列表,请参考官网文档:2.3.2. Modifying Unit Files1.2 试验阐明以MySQL CPU资源管理为例。 环境信息: 零碎版本:CentOS Linux release 7.5.1804 (Core) CPU配置:4核CPU当资源限度为1核CPU时(CPUQuota=100%): 批改CPU资源配置为:2核(CPUQuota=200%) 再次测试,能够看到数据库在写入数据的过程中,%CPU的值固定在200%左右。 二,简要原理阐明系统资源在cgroup里体现为资源控制器(resource controller/cgroup subsystem);每个controller以层级目录构造的形式对系统资源进行治理。systemd在零碎开机时,默认主动将cpu、blkio、memory等控制器挂载到/sys/fs/cgroup门路下。 systemd应用以下三种类型的unit来进行资源管理: service:A system serviceslice:A group of hierarchically organized units that manage system processscope:An externally created process其中scope类型只能由程序主动创立;其余两种可程序主动创立,也可手动创立。零碎在启动的时候将默认创立一系列运行时必要的service,同时也会创立四种必要的slice: -.slice — the root slice;system.slice — the default place for all system services;user.slice — the default place for all user sessions;machine.slice — the default place for all virtual machines and Linux containers.基于此,在Linux 7中,零碎通过绑定程序的systemd层级树门路和cgroup资源控制器门路实现资源隔离(可应用命令systemd-cgls直观查看,见下文图片),具体表现为: ...

July 22, 2020 · 1 min · jiezi

从一个实际案例来讨论我们应该如何做性能优化

如何优化一个数据解析器?注:本文所示代码均为伪代码 假设我们要编写一个函数function parse_data(String Raw):Object[] 用来解析一个列表数据到应用程序之中。在二十一世纪的今天,我们会很自然的联想到使用JSON来完成这项需求。因为我们可以脱口而出JSON所有的优点: 1. 兼容性良好。2. 开源支持力度好。3. 人类阅读友好。因此,我们可以很快速的得到一个实现版本。 function parse_data(String raw): Object[] { let lst: Object[]; lst = JSON.parse_into<Object[]>)(raw) return lst }在相当多的场景里面,以上的实现都堪称完美。假设我们将程序的运行条件限定一下: 1. raw String 可能超过 1GB2. 物理内存只有256MB在以上场景的约束下,第一个实现已经无法正常工作了。因为JSON格式必须将其完整的载入内存才可以进行解析,从约束条件来看,raw string 大小已经远远超过了内存限制;同时,将所有数据都解析到内存也是很大的内存开销。从这个分析来看,我们得出了一个结论:第一个版本无法在内存条件苛刻的情况下工作,因此我们需要进行优化。 那么,我们的优化的思考点应该是怎么样的嘞? 我们需要先回过头了看问题,第一个实现的问题是内存占用过大引起的。那么,我们就需要一个方案来减少内存的占用。 减少运行时内存占用 -- 这个就是我们本次优化的哲学指导。 我们已经有了基本的哲学指导思想,那么我们开始进入到具体问题具体分析的阶段去寻找解决方案。我们再深入的思考第一个实现为什么会造成内存占用高: 1. 需要全部载入数据2. 需要全部将解析结果存到内存也就是说,我们的新方案只需要解决上面两个问题,也就完成了目标。 经过一番搜索与学习,我们发现可以使用Streaming友好的数据格式(Msgpack,CSV)来作为raw string,同时将数据使用sqlite来存储解析后的结果。 此时此刻,我们就得到了第二个实现版本。 function parse_data(String filePath): Object[] { let db_conn = Sqlite.open("./cache.db") CsvReader .open(filePath) .each((line)=>{ db_conn.insert_into(convert_line_to_object(line)) })}这个实现通过将raw string 放入磁盘,同时利用csv行间隔离的特性。通过流式的方式将数据迁移到本地db中。对于物理内存的需求基本是趋近于O(1)的。从而解决了我们上面提出的两个问题。 那么,这个版本就完美了吗? 从代码逻辑上来看,这个版本对于数据量的限制从内存转移到了磁盘,在实际过程中可以认为解决了数据量代码无法工作的问题。但是它仍然存在一个问题 -- 磁盘IO过于频繁,磁盘IO表现在两个方面: 1. 读取csv2. 写入sqlite那么,我们是否有可能再次优化嘞? ...

July 5, 2020 · 1 min · jiezi