关于优化:记一次对代码优化的经历

1. 复杂度不会隐没,只会转移新建工具类文件,把一些判断的逻辑抽离进来2. 形象,就是像做数学题一样总结一种办法把具备雷同作用的逻辑提取出他们的公式先拆分,后重构在传参为空时,给出默认值和校验提醒,避免一些调用引发的BUG3. 默认值,数据类型校验和try/catch/finally语句,是爱护程序平安运行的三剑客4. 文件放入文件夹,分类排好,把代码依照性能拆散,放入相应的文件夹中就像拾掇衣服一样,把不同节令的打底衣服,外套,内衣裤分凋谢5.缩小因为版本更迭产生的反复而无用的逻辑,代码,变量和死循环依据热力学第二定律,孤立零碎的熵永不主动缩小,熵在可逆过程中不变,在不可逆过程中减少。整个我的项目只调用一次的函数形象应该和调用者函数合并6.编写文档和正文7.在重构时就会领会到面向对象比照面向流程的长处一但流程变动,整个链条都会断掉知乎答主justjavac的一句话解决了我脑中始终以来的困惑:“优化的实质就是给V8写代码。如果是业务代码,要优雅,写给人看;如果是库代码,要高效,写给V8去运行。”原话起源:https://zhuanlan.zhihu.com/p/...

January 30, 2022 · 1 min · jiezi

关于优化:屏幕后处理效果系列之常见后处理效果篇

1.1 前言在系列第一篇中,咱们学习了用于图像含糊的相干算法,在探索这些算法效率高下的同时,深刻了解了这些算法的核心思想,这些思维将会被利用于许多后处理成果中。接下来,咱们将学习一些常见的屏幕后处理成果的实现形式。 1.2 基础知识 Bloom(Glow)特效是游戏中利用最广泛的一种屏幕后处理特效。体现为高光物体带有泛光成果,使画面的光影体现更加优良。Bloom通常会搭配HDR和ToneMapping来失去更好的成果。 首先咱们须要简略理解一下什么是HDR和ToneMapping。电子设备能够显示的亮度范畴无限,对于RGB三个通道,每个通道8bit,由此以来能够显示(2^8)^3=16777216种颜色,这个范畴被称为低动静范畴(Low-Dynamic Range)。这个范畴是一个教训亮度范畴,在这个范畴内不会对人眼产生挫伤,而超出这个范畴的色彩空间被称为高动静范畴(High-Dynamic Range)。现实生活中的亮度是没有范畴限度的,想要表白更多的亮度,RGB每个通道须要裁减到12位乃至更多。运算实现后,在进行输入时须要通过ToneMapping将HDR空间中的色彩映射到LDR空间中,再在显示器上进行显示。 现实生活中,Bloom产生的起因是人眼晶状体的散射,例如在强光照耀的时候,会有看不清的状况产生。于是应用Bloom来体现高光溢出的成果从而模仿这种景象。 对于HDR 、 LDR、ToneMapping的更多知识点能够学习《漫谈HDR和色调治理》。 通用的Bloom特效的制作形式是将图像高亮的局部通过卷积进行含糊之后再叠加到原图像上。在《屏幕后处理成果系列之图像含糊算法篇》课程中,咱们介绍了各种图像含糊的算法,抉择应用效率最高的Dual Blur的形式进行含糊解决。 1.3 Unity实现 首先设定阈值,采样图片,对于图片中超过阈值的像素被断定为高亮局部。高亮局部,保留色彩,其余部分归0,存储在一张RT中。 BloomMaterial.SetFloat("_Threhold", threshold);BloomMaterial.SetFloat("_Intensity", intensity);RenderTexture HighLighrRT=RenderTexture.GetTemporary(src.descriptor);Graphics.Blit(src, HighLighrRT, BloomMaterial, 0);Boom.shader:Pass{ CGPROGRAM #pragma vertex vert_img #pragma fragment frag fixed4 frag(v2f_img input) : SV_Target { float4 color = tex2D(_MainTex, input.uv); return max(color - _Threhold, 0) * _Intensity; } ENDCG}接着,将失去的高亮局部进行含糊解决后叠加在原图上: Pass{ CGPROGRAM #pragma vertex vert_img #pragma fragment frag sampler2D _CompositeTex; float4 _CompositeColor; fixed4 frag(v2f_img input) : SV_Target{ float4 mainColor = tex2D(_MainTex,input.uv); float4 compositeColor = tex2D(_CompositeTex, input.uv); return saturate(mainColor + compositeColor);} ENDCG}失去成果如图: ...

August 30, 2021 · 1 min · jiezi

关于优化:两行代码显存翻倍2080Ti也能当V100来用这个炼丹神器真牛

| 作者:邓哲也 | 旷视 MegEngine 基础架构组工程师 在近年来的深度学习畛域,许多钻研机构和研究者通过增大模型的参数量来晋升模型的体现,获得了十分显著的成绩,一次次令业界称奇。这主观上使得“扩充模型的尺寸”简直一度成为各家竞相追赶的惟一指标。几年间,最先进的模型的参数量已减少了成千盈百倍,但每张 GPU 的显存大小却简直没有增长。这导致大模型的训练往往依赖于巨量的 GPU 卡数。于是,很多想法杰出、有钻研激情的研究者单纯因为资金不足,难以持续从事深度学习的钻研,而近年里的重要科研成果也简直都是被几家头部钻研机构所垄断。从长远看来,这种趋势未必有利于深度学习这门迷信的倒退提高。 作为深度学习训练框架的开发者,咱们除了帮忙用户在一个训练任务中利用更多的 GPU 卡(即分布式训练)之外,还采纳了各种技术手段,以减少每张 GPU 上显存的利用效率,升高研究者的资金老本。减少显存利用效率的常见办法有: 生命周期不重叠的算子共享显存;通过额定的数据传输缩小显存占用;通过额定的计算缩小显存占用。目前已有的办法中大多都要求计算图是动态的,随着越来越多的框架反对动态图模式,是否在动态图训练时最大水平地利用无限的显存资源,成为了评估深度学习框架性能的重要指标。MegEngine 在近期公布的v1.4 版本中,通过引入 DTR[[1]](https://arxiv.org/abs/2006.09... 技术并进行进一步的工程优化,提供了一种通过额定计算缩小显存占用的路径,从而让小显存也能训练大模型,享受更大 batch size 所带来的训练收益。在 2080Ti 上,ResNet-50、ShuffleNet 等网络的最大 batch size 能够达到原来的 3 倍以上。本篇文章将从工程实现的角度重点介绍在 MegEngine 中如何应用 DTR 技术对动态图显存进行优化的。 一、背景介绍1.1 计算图在深度学习畛域,神经网络模型实质上都能够用一个计算图来示意。它的训练过程能够分为三个局部:前向流传,反向流传,参数更新。 以 y=wx+b 为例,它的前向计算过程为输出 x 和参数 w 首先通过乘法运算失去两头后果 p,接着 p 和参数 b 通过加法运算,失去右侧最终的输入 y。 反向流传需要求出 y 对于 w 与 b 的导数,首先求出 y 对于 p 的导数是 1,p 对于 w的导数是 x,应用链式法则就能够失去 y对于 w 的导数是 x。 ...

August 3, 2021 · 3 min · jiezi

关于优化:性能优化提升

1.节流 从滚动条监听的例子说起: 监听浏览器滚动事件,返回以后滚条与顶部的间隔 function showTop() { var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log("滚动条地位: " + scrollTop);}window.onscroll = showTop;在运行的时候会发现存在一个问题:这个函数的默认执行频率,太!高!了!。 高到什么水平呢?以chrome为例,咱们能够点击选中一个页面的滚动条,而后点击一次键盘的【向下方向键】,会发现函数执行了8-9次! 然而实际上咱们并不需要如此高频的反馈,毕竟浏览器的性能是无限的,不应该节约在这里,所以接着探讨如何优化这种场景。 防抖(debounce) 在第一次触发事件时,不立刻执行函数,而是给出一个期限值,比方200ms,而后, 如果在200ms内没有再次触发滚动事件,那么就执行函数如果200ms内再次触发滚动事件,那么以后的计时勾销,重现开始计时成果:实现如果短时间内触发对立事件,那么只会执行一次函数实现:既然后面都提到了计时,那实现的要害就在于setTimeout这个函数,因为还须要一个变量来保留计时,思考保护全局污浊,能够借助闭包来实现: /** * fn: function 须要防抖的函数 * delay: number 防抖期限值 */function debounce(fn, delay) { let timer = null; // 借助闭包 return function () { if(timer) { clearTimeout(time); } timer = setTimeout(fn, delay); }}window.onscroll = debounce(showTop, 1000);window.onscroll = debounce(showTop, 1000);此时会发现,必须在进行滚动1秒当前,才会打印出滚动条地位。 到这里,曾经把防抖实现了,当初给出定义: 对于短时间内间断触发的事件(下面的滚动事件),防抖的含意就是让某个工夫期限(如下面的1000毫秒)内,事件处理函数只执行一次。 2.节流(throttle) 持续思考,应用下面的防抖计划来解决问题的后果是: 如果在限定时间段内,一直触发滚动事件(比方某个用户闲着无聊,按住滚动一直的拖来拖去),只有不进行触发,实践上就永远不会输入以后间隔顶部的间隔。 然而如果产品同学的冀望解决计划是:即便用户一直拖动滚动条,也能在某个工夫距离之后给出反馈呢? 咱们能够设计一种相似管制阀门一样定期凋谢的函数,也就是让函数执行一次后,在某个时间段内临时生效,过了这段时间后再从新激活 成果:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的工夫期限内不再工作,直至过了这段时间才从新失效。 ...

July 22, 2021 · 1 min · jiezi

关于优化:多维分析后台实践-2数据类型优化

【摘要】用实例、分步骤,具体解说多维分析(OLAP)的实现。点击理解多维分析后盾实际 2:数据类型优化 实际指标本期指标是练习将数据库读出的数据,尽可能转换为有利于性能优化的数据类型,例如:小整数和浮点数。 实际的步骤: 1、 筹备根底宽表:批改上期的代码,实现数据类型优化存为组表文件。 2、 拜访根底宽表:批改上期的代码,在传入参数放弃不变的前提下,查问数据转换之后的组表文件,后果集也要返回原有的数据显示值。对于这个要求,SQL 是无奈实现传入参数和后果集的转换的,所以拜访宽表的代码以 SPL 为例。 本期样例宽表不变,仍然为 customer 表。从 Oracle 数据库中取出宽表数据的 SQL 语句是 select * from customer。执行后果如下图: 其中字段包含: CUSTOMER_ID NUMBER(10,0), 客户编号 FIRST_NAME VARCHAR2(20), 名 LAST_NAME VARCHAR2(25), 姓 PHONE_NUMBER VARCHAR2(20), 电话号码 BEGIN_DATE DATE, 开户日期 JOB_ID VARCHAR2(10), 职业编号 JOB_TITLE VARCHAR2(32), 职业名称 BALANCE NUMBER(8,2), 余额 EMPLOYEE_ID NUMBER(4,0), 开户雇员编号 DEPARTMENT_ID NUMBER(4,0), 分支机构编号 DEPARTMENT_NAME VARCHAR2(32), 分支构造名称 FLAG1 CHAR(1), 标记 1 FLAG2 CHAR(1), 标记 2 FLAG3 CHAR(1), 标记 3 FLAG4 CHAR(1), 标记 4 FLAG5 CHAR(1), 标记 5 ...

January 22, 2021 · 3 min · jiezi

关于优化:2020年度大赏-UWA问答精选

UWA每周推送的知识型栏目《厚积薄发 | 技术分享》曾经随同大家走过了252个工作周。精选了2020年十大精彩问答分享给大家,期待2021年UWA问答持续有您的陪伴。 UWA 问答社区:answer.uwa4d.comUWA QQ群2:793972859(原群已满员) Q1:IL2CPP的内存问题最近看问答下面有个对于IL2CPP和Mono的比照,看到IL2CPP内存冲高会降落。对于这个,我问了Unity的官网技术,答复是:你好,Unity有本人的GC机制,为了防止频繁向操作系统申请/开释内存,Reserved Mono值会放弃在肯定区间内,达到某些条件或在某些非凡状况才会触发GC。 有人说是:“内存池治理逻辑都是一样的,属于下层治理一样。它们只是两头语言不一样而已,也是只涨不降。”也有其余大佬说是IL2CPP冲高会降落。当初很困惑,求解答。 A:看下来题主说的内存冲高不降,波及两个指标,一个是Profiler里的Reserved Mono,一个是设施内存(PSS)。目前的确没有权威的文档阐明这一点,所以上面通过实在数据来阐明一下。 先说第一个(Reserved Mono)。 在Script Backend是Mono的状况下,如果抉择的是旧版本里的Mono 2.x,或者新版本里的 .Net 3.5(Runtime Version),那么这个值是只升不降的。比方这个数据,Unused曾经很高了,但也不会降落: 同样在Script Backend是Mono的状况下,如果抉择的是.Net 4.x (Runtime Version),那么这个值是能够降落的(但不确定具体是从哪个版本开始的)。比方这个数据,能够看出尽管会降落,也并不是频繁执行降落操作的: 最初Script Backend是IL2CPP的状况下,那么这个值也是能够降落的。比方这个数据,看上去和下面的状况相差不是太大: 而对于第二个,设施内存。这个就和安卓零碎的内存管理机制无关了,即便Unity把Reserved Mono升高了,缩小了本身的内存占用,零碎也不肯定会立刻会把这块内存开释,所以这里的行为就很难说分明了。 该答复由UWA提供 Q2:加载配置内存过大问题配置表太多占用内存过大时,除了采纳Sqlite,还有什么好的解决办法没有,有没有大佬是否指导下。FlatBuffer不必全副进内存吗?如果不全副进内存,访问速度如何呢? A1:第一问题参考如下: 能够针对反复数据进行剔除,尤其是一些字符串的配置。在配置导出时把这样的数据提取一份,其余用到的中央只是援用,会节俭不少。数据类型要正当。能够应用相似FlatBuffer/ZeroFormatter的提早加载的思路,在真正应用时再去反序列化。一次游戏过程中理论用到的配置量比拟无限,应用这种策略能够尽可能的缩小不必要数据的加载。第二个问题参考如下:咱们上个我的项目也是到前期优化时遇到相似问题,只是参考了这种思路,并没有进行齐全替换。咱们过后在打包时,会对配置以行为单位,进行Offset和Length的计算,在Runtime阶段,初始加载只会加载每行的ID,对应的这一行的Offset和Length,而后后续逻辑调用配置表接口拿数据的时候,如果发现没有反序列化过,就依据Offset和Length再去构建一下相应的数据提供给下层。访问速度的话必定不如开始间接全副加载好,但咱们测下来影响不大。 感激范君@UWA问答社区提供了答复 A2:字符串吃内存不说了,尽量少用或者复用。表格中比拟多的会是那种:攻打-1000;进攻-2000;血量-3000,每个int都是4个字节,数量多了会顶不住。这种能够思考用一个int32/int64/uint32/uint64 去存多个数值。感激萧小俊@UWA问答社区提供了答复 Q3:Instruments如何看Mono内存调配例如在调配了一个10MB数组,对应在Unity Profiler中会看到开拓了至多10MB大小的Mono内存。 那么在Instruments中,如何查看调配的内存信息呢?Allocations中的信息是此过程中调配的所有内存信息吗,尝试调配过100MB内存,Allocations中的统计没有任何增长。 A:我这边也做了测试: 创立了100MB大小的int数组,Size理论应该是400MB。 而后到Profiler察看: 能够看到ManagedHeap正确调配了这400MB的空间。 而后打包iOS后到xCode运行,运行前首先吧Run这个Scheme的Malloc Stack勾上: Run当前点选Memory并导出Memory Graph来察看: 因为应用程序的内存都是在VirtualMemory空间调配的,因而查看VM Regions的VM_ALLOCATE局部。 于是就可已发现128X3+16刚好400MB的调配。调用堆栈也很好确定: 正式咱们的测试代码。 而后咱们来看Instruments。首先是Allocations局部,有一点要留神,该栏的下部有一些选项: 留神最初一个选项,如果抉择第一个:All Heap & Anonymous VM,All Heap对应App理论调配的物理空间,不蕴含VM, Anonymous VM的官网解释是:interesting VM regions such as graphics- and Core Data-related. Hides mapped files, dylibs, and some large reserved VM regions。 ...

January 11, 2021 · 3 min · jiezi

关于优化:2020年度大赏-UWA问答精选

UWA每周推送的知识型栏目《厚积薄发 | 技术分享》曾经随同大家走过了252个工作周。精选了2020年十大精彩问答分享给大家,期待2021年UWA问答持续有您的陪伴。 UWA 问答社区:answer.uwa4d.comUWA QQ群2:793972859(原群已满员) Q1:IL2CPP的内存问题最近看问答下面有个对于IL2CPP和Mono的比照,看到IL2CPP内存冲高会降落。对于这个,我问了Unity的官网技术,答复是:你好,Unity有本人的GC机制,为了防止频繁向操作系统申请/开释内存,Reserved Mono值会放弃在肯定区间内,达到某些条件或在某些非凡状况才会触发GC。 有人说是:“内存池治理逻辑都是一样的,属于下层治理一样。它们只是两头语言不一样而已,也是只涨不降。”也有其余大佬说是IL2CPP冲高会降落。当初很困惑,求解答。 A:看下来题主说的内存冲高不降,波及两个指标,一个是Profiler里的Reserved Mono,一个是设施内存(PSS)。目前的确没有权威的文档阐明这一点,所以上面通过实在数据来阐明一下。 先说第一个(Reserved Mono)。 在Script Backend是Mono的状况下,如果抉择的是旧版本里的Mono 2.x,或者新版本里的 .Net 3.5(Runtime Version),那么这个值是只升不降的。比方这个数据,Unused曾经很高了,但也不会降落: 同样在Script Backend是Mono的状况下,如果抉择的是.Net 4.x (Runtime Version),那么这个值是能够降落的(但不确定具体是从哪个版本开始的)。比方这个数据,能够看出尽管会降落,也并不是频繁执行降落操作的: 最初Script Backend是IL2CPP的状况下,那么这个值也是能够降落的。比方这个数据,看上去和下面的状况相差不是太大: 而对于第二个,设施内存。这个就和安卓零碎的内存管理机制无关了,即便Unity把Reserved Mono升高了,缩小了本身的内存占用,零碎也不肯定会立刻会把这块内存开释,所以这里的行为就很难说分明了。 该答复由UWA提供 Q2:加载配置内存过大问题配置表太多占用内存过大时,除了采纳Sqlite,还有什么好的解决办法没有,有没有大佬是否指导下。FlatBuffer不必全副进内存吗?如果不全副进内存,访问速度如何呢? A1:第一问题参考如下: 能够针对反复数据进行剔除,尤其是一些字符串的配置。在配置导出时把这样的数据提取一份,其余用到的中央只是援用,会节俭不少。数据类型要正当。能够应用相似FlatBuffer/ZeroFormatter的提早加载的思路,在真正应用时再去反序列化。一次游戏过程中理论用到的配置量比拟无限,应用这种策略能够尽可能的缩小不必要数据的加载。第二个问题参考如下:咱们上个我的项目也是到前期优化时遇到相似问题,只是参考了这种思路,并没有进行齐全替换。咱们过后在打包时,会对配置以行为单位,进行Offset和Length的计算,在Runtime阶段,初始加载只会加载每行的ID,对应的这一行的Offset和Length,而后后续逻辑调用配置表接口拿数据的时候,如果发现没有反序列化过,就依据Offset和Length再去构建一下相应的数据提供给下层。访问速度的话必定不如开始间接全副加载好,但咱们测下来影响不大。 感激范君@UWA问答社区提供了答复 A2:字符串吃内存不说了,尽量少用或者复用。表格中比拟多的会是那种:攻打-1000;进攻-2000;血量-3000,每个int都是4个字节,数量多了会顶不住。这种能够思考用一个int32/int64/uint32/uint64 去存多个数值。感激萧小俊@UWA问答社区提供了答复 Q3:Instruments如何看Mono内存调配例如在调配了一个10MB数组,对应在Unity Profiler中会看到开拓了至多10MB大小的Mono内存。 那么在Instruments中,如何查看调配的内存信息呢?Allocations中的信息是此过程中调配的所有内存信息吗,尝试调配过100MB内存,Allocations中的统计没有任何增长。 A:我这边也做了测试: 创立了100MB大小的int数组,Size理论应该是400MB。 而后到Profiler察看: 能够看到ManagedHeap正确调配了这400MB的空间。 而后打包iOS后到xCode运行,运行前首先吧Run这个Scheme的Malloc Stack勾上: Run当前点选Memory并导出Memory Graph来察看: 因为应用程序的内存都是在VirtualMemory空间调配的,因而查看VM Regions的VM_ALLOCATE局部。 于是就可已发现128X3+16刚好400MB的调配。调用堆栈也很好确定: 正式咱们的测试代码。 而后咱们来看Instruments。首先是Allocations局部,有一点要留神,该栏的下部有一些选项: 留神最初一个选项,如果抉择第一个:All Heap & Anonymous VM,All Heap对应App理论调配的物理空间,不蕴含VM, Anonymous VM的官网解释是:interesting VM regions such as graphics- and Core Data-related. Hides mapped files, dylibs, and some large reserved VM regions。 ...

January 11, 2021 · 3 min · jiezi

关于优化:性能优化技巧前半有序时的排序

一、  问题背景与实用场景在对数据集进行排序运算时,有时会遇到这样一种场景:数据集T曾经按字段a有序,而字段b无序,当初咱们要将T按a、b排序,咱们称之为前半有序(a有序)的排序。此时咱们能想到一种优化的排序办法:从T中先取出a值雷同的一组记录,再这一组内对b排序。而后再顺次取出下一组a值雷同的记录,反复这个动作,直到实现T中所有记录的排序。这种办法的益处是不须要对T中所有记录进行大排序,一次只需取出一小组,对内存容量要求大大减低,只需能装下每个小组即可。 遗憾的是SQL并不反对这种优化算法,只能所有记录进行大排序,而SPL提供了对这种算法的反对,上面咱们实例测试一下,并与Oracle作比照。 二、  测试环境与工作测试机有两个Intel2670 CPU,主频2.6G,共16核,内存64G,SSD固态硬盘。在此机上安装虚拟机来测试,设置虚拟机为16核、8G内存。 在虚拟机上创立数据表salesman1,共两个字段:area(字符串)、salesman(字符串),生成数据记录4亿行,按area升序排列,area不同值共2000个,每个area对应salesman为20万个。将此表数据导入Oracle数据库,同时用它生成集算器SPL组表来进行测试。 再建另一张表salesman2作大数据量测试,数据表构造不变,总数据记录20亿行,area值4000个,每个area对应50万个salesman。 测试工作都是要对表依照area、salesman排序。 三、  小数据量测试1.  Oracle测试编写测试SQL如下: select area, salesman from salesman1 order by area, salesman 原本只需这一句简略的SQL即可,不过这个排序后果的输入工夫却十分长,为了缩小输出量,只统计排序过程的用时,咱们不输入排序后的全副后果,而只输入两头地位的一行,也就是行号为2亿的那一行,所以SQL语句改写如下: select area, salesman from (        select area, salesman, rownum rn from (               select area, salesman from salesman1 order by area, salesman        ) ) where rn=200000000; 要多说一句,这个查问其实没有什么业务意义,纯正是为了迫使数据库大排序且防止统计输入工夫的 。 2.  SPL测试编写SPL脚本如下: group@qs中选项s示意对数据集只排序,不分组;选项q示意数据集对分号前的分组表达式(area)是有序的,申请应用前半有序时的排序办法按分号后的表达式(salesman)排序。 四、  大数据量测试1.  Oracle测试编写测试SQL如下: select area, salesman from (        select area, salesman, rownum rn from (               select area, salesman from salesman2 order by area, salesman ...

December 3, 2020 · 1 min · jiezi

关于优化:技术分享-优化案例

作者:杨奇龙网名“北在北方”,目前任职于杭州有赞科技 DBA,次要负责数据库架构设计和运维平台开发工作,善于数据库性能调优、故障诊断。本文起源:原创投稿*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。前言在数据库表构造变更公布之前,咱们会和开发沟通索引设计是否正当,发现局部开发同学对于索引设计还是有一些常识盲区。本文把常见的案例记录下来,做个剖析,抛砖引玉。 区分度和过滤性先看一段和开发同学日常 sql review 的对话: 下面的对话其实在工作中比拟常见(同时也阐明咱们培训没有到位 T_T),这样的想法会导致开发疏忽选择性比拟低的字段,sql 的执行打算应用 using where 匹配更多的数据行,后果执行耗时比拟,性能就不现实。大部分开发会理解这样的《开发标准》:创立索引要抉择区分度高的字段。他们会认为区分度低的字段不适宜创立索引或者不适宜增加到组合索引外面。然而这样的操作会导致很多慢查。举例来说: select * from tab where a=1 and b=2;场景 1 合乎 a=1 的记录数有 10w 条记录 ,b=2 有 1000 条记录。如果只是创立 idx_a(a),sql 申请通过索引 idx_a 拜访 10w 条件记录,而后还要逐个匹配 10w 条记录中的 status,找到合乎 b=2 的记录。这个动作会导致慢查。如果创立组合索引 idx_ab(a,b),sql 申请通过索引 idx_ab 能够间接定位到 1000 条记录,无需额定的过滤。这样缩小拜访 9900 条记录的工夫,晋升查问速度。 场景 2 合乎 a=1 的有 100 条记录,status=2 有 10 条记录。其实场景 2 因为数据量比拟少,间接拜访 100 条记录和定位到 10 条记录的工夫耗费相差不大,质变不足以引发量变,能够疏忽了。 Tips:创立索引的目标是通过索引尽可能找到匹配 where 条件的行,缩小不必要的回表,进步查问效率;须要辩证地对待区分度比拟低的字段在组合索引中的作用。在组合索引的状况下,咱们不能只是单纯地看字段的区分度,而是要看符合条件的记录数是多少。符合条件的记录越少,性能越好。索引的有序性在优化业务 sql 的过程中,常常发现开发将 order by 的字段增加到组合索引外面,然而仍然有 file sort 产生,导致慢查。这是为什么呢?索引自身是有序的,之所以产生 file sort 阐明组合索引中存在字段在索引中存储的程序和order by 字段的程序不统一,不是严格正相干导致 MySQL 依据后果从新排序。order by 语句利用索引的有序性是有比拟高要求的,组合索引中 order by 之前的字段必须是等值查问,不能是 in、between、<、> 等范畴查问,explain 的 type 是 range 的 sql 都会导致 order by 不能失常利用索引的有序性。入手实际一下,初始化一张表 x ...

November 26, 2020 · 2 min · jiezi

关于优化:什么你的电脑太渣这几招包你搞定-Win10优化教程

每当你们在编程或者工作的时候,就须要关上很多软件,就像这样:而后,你的(渣机)电脑就变成了这样:而后,你的电脑不是变成这样:就是这样:而后,你就会:https://www.bilibili.com/vide...所以,这个时候,咱们就须要搞机对电脑优化一下了。首先,我要介绍两款咱们的优化软件,它们别离是:www.sysinternals.com(RAMMap)和https://coderbag.com/assets/downloads/cpm/currentversion/QuickCpuSetup64.zip(qiuckCPU)在RAMMap中,你只需找到empty这一项(在右上角)点开它,把外面的每一项不反复的点一下你的电脑就变成了这样:再关上qiuckCPU点击向上的箭头(也在右上角)再点击确定就能够了。另外,如果在工作之余,想要玩游戏的人能够……………………期待下一期了。而后,开始咱们的其余教程。首先,关上设置,搜寻告诉与操作,把全副选项都敞开,再把专一助手敞开。找到平板模式,调成不询问,不切换选项,再关上游戏模式(本人找)把游戏DVR和true play敞开(如果你有的话),把多任务处理外面的全副选项敞开,把上面的两个选项改成仅限我只能在应用的桌面,敞开远程桌面。好的,咱们的电脑优化教程就完结了,(制作不易,求打赏)打赏国20光速更新游戏优化教程。咱们下次再见,88.

November 7, 2020 · 1 min · jiezi

关于优化:将-20M-文件从-30-秒压缩到-1-秒我是如何做到的

作者:不学有数的程序员,原文链接:https://urlify.cn/7NRrea压缩20M文件从30秒到1秒的优化过程有一个需要须要将前端传过来的10张照片,而后后端进行解决当前压缩成一个压缩包通过网络流传输入去。之前没有接触过用Java压缩文件的,所以就间接上网找了一个例子改了一下用了,改完当前也能应用,然而随着前端所传图片的大小越来越大的时候,消耗的工夫也在急剧减少,最初测了一下压缩20M的文件居然须要30秒的工夫。压缩文件的代码如下。 这里找了一张2M大小的图片,并且循环十次进行测试。打印的后果如下,工夫大略是30秒。 第一次优化过程-从30秒到2秒进行优化首先想到的是利用缓冲区 BufferInputStream。在FileInputStream中read() 办法每次只读取一个字节。源码中也有阐明。 这是一个调用本地办法与原生操作系统进行交互,从磁盘中读取数据。每读取一个字节的数据就调用一次本地办法与操作系统交互,是十分耗时的。例如咱们当初有30000个字节的数据,如果应用FileInputStream那么就须要调用30000次的本地办法来获取这些数据,而如果应用缓冲区的话(这里假如初始的缓冲区大小足够放下30000字节的数据)那么只须要调用一次就行。因为缓冲区在第一次调用read()办法的时候会间接从磁盘中将数据间接读取到内存中。随后再一个字节一个字节的缓缓返回。 BufferedInputStream外部封装了一个byte数组用于存放数据,默认大小是8192优化过后的代码如下 输入 能够看到相比拟于第一次应用FileInputStream效率曾经晋升了许多了 第二次优化过程-从2秒到1秒应用缓冲区buffer的话曾经是满足了我的需要了,然而秉着学以致用的想法,就想着用NIO中常识进行优化一下。 应用Channel 为什么要用Channel呢?因为在NIO中新出了Channel和ByteBuffer。正是因为它们的构造更加合乎操作系统执行I/O的形式,所以其速度相比拟于传统IO而言速度有了显著的进步。Channel就像一个蕴含着煤矿的矿藏,而ByteBuffer则是派送到矿藏的卡车。也就是说咱们与数据的交互都是与ByteBuffer的交互。 在NIO中可能产生FileChannel的有三个类。别离是FileInputStream、FileOutputStream、以及既能读又能写的RandomAccessFile。 源码如下 咱们能够看到这里并没有应用ByteBuffer进行数据传输,而是应用了transferTo的办法。这个办法是将两个通道进行直连。 这是源码上的形容文字,大略意思就是应用transferTo的效率比循环一个Channel读取进去而后再循环写入另一个Channel好。操作系统可能间接传输字节从文件系统缓存到指标的Channel中,而不须要理论的copy阶段。 copy阶段就是从内核空间转到用户空间的一个过程能够看到速度相比拟应用缓冲区曾经有了一些的进步。 内核空间和用户空间 那么为什么从内核空间转向用户空间这段过程会慢呢?首先咱们需理解的是什么是内核空间和用户空间。在罕用的操作系统中为了爱护零碎中的外围资源,于是将零碎设计为四个区域,越往里权限越大,所以Ring0被称之为内核空间,用来拜访一些关键性的资源。Ring3被称之为用户空间。 用户态、内核态:线程处于内核空间称之为内核态,线程处于用户空间属于用户态那么咱们如果此时应用程序(应用程序是都属于用户态的)须要拜访外围资源怎么办呢?那就须要调用内核中所暴露出的接口用以调用,称之为零碎调用。例如此时咱们应用程序须要拜访磁盘上的文件。此时应用程序就会调用零碎调用的接口open办法,而后内核去拜访磁盘中的文件,将文件内容返回给应用程序。大抵的流程如下 间接缓冲区和非间接缓冲区既然咱们要读取一个磁盘的文件,要废这么大的周折。有没有什么简略的办法可能使咱们的利用间接操作磁盘文件,不须要内核进行直达呢?有,那就是建设间接缓冲区了。 非间接缓冲区:非间接缓冲区就是咱们下面所讲内核态作为中间人,每次都须要内核在两头作为直达。 间接缓冲区:间接缓冲区不须要内核空间作为直达copy数据,而是间接在物理内存申请一块空间,这块空间映射到内核地址空间和用户地址空间,应用程序与磁盘之间数据的存取通过这块间接申请的物理内存进行交互。 既然间接缓冲区那么快,咱们为什么不都用间接缓冲区呢?其实间接缓冲区有以下的毛病。间接缓冲区的毛病: 不平安耗费更多,因为它不是在JVM中间接开拓空间。这部分内存的回收只能依赖于垃圾回收机制,垃圾什么时候回收不受咱们管制。数据写入物理内存缓冲区中,程序就丢失了对这些数据的治理,即什么时候这些数据被最终写入从磁盘只能由操作系统来决定,应用程序无奈再干预。综上所述,所以咱们应用transferTo办法就是间接开拓了一段间接缓冲区。所以性能相比而言进步了许多应用内存映射文件NIO中新出的另一个个性就是内存映射文件,内存映射文件为什么速度快呢?其实起因和下面所讲的一样,也是在内存中开拓了一段间接缓冲区。与数据间接作交互。源码如下 打印如下 能够看到速度和应用Channel的速度差不多的。 应用PipeJava NIO 管道是2个线程之间的单向数据连贯。Pipe有一个source通道和一个sink通道。其中source通道用于读取数据,sink通道用于写入数据。能够看到源码中的介绍,大略意思就是写入线程会阻塞至有读线程从通道中读取数据。如果没有数据可读,读线程也会阻塞至写线程写入数据。直至通道敞开。 Whether or not a thread writing bytes to a pipe will block until another thread reads those bytes我想要的成果是这样的。源码如下: 源码地址https://github.com/modouxiansheng/Doraemon ...

September 14, 2020 · 1 min · jiezi

关于优化:UWA-五周年-我们的长期主义刚刚开始

转眼之间,UWA步入了第六个年头。 UWA,从一个石破天惊的产品,缓缓成长为业界略有出名的服务商。借这个有留念意义的日子,和大家分享一些咱们的故事。 UWA的倒退经验几个过程:从0到0.1,通过工具化解决技术层面的性能问题;从0.1到1,通过体系化优化流程层面的问题。将来,UWA也将继续深耕于优化方面,把一米宽的市场做到一百米深。 从0到0.1:解决上线前的优化问题五年前的UWA,在上海某个园区里的一间小小办公室起航。过后的守业思路很简略,用咱们所把握的技术,去帮忙天下开发者解决上线前后的性能优化问题。那时候Unity引擎在国内的发展势头大增,优化需要正是强烈,咱们在短期工夫内疾速帮到了一群敢于尝鲜的开发者,而当初这群人经常会聊起这句话:哎呀,咱们当年也是见证UWA成长起来的呢。 UWA是一家技术服务型公司,UWA人的价值观之一是用户第一。如何做到?咱们给本人定的规范是:快、精准、有温度。 “快”和“精准”是把产品打造得简略易用、业余精确。咱们置信应用的形式越容易、反馈的效率越高效、剖析和提供的解决方案越精准,用户解决问题就会越简略。 “有温度”是提供人与人沟通的平台,而不是凉飕飕的数字。咱们心愿用户能感触到UWA产品中的温度:敌对性、专业性和亲和性。 从那时起,大家开始逐渐晓得咱们UWA是做优化的,如果性能不达标,那去UWA上提个包测一测。用得好的,降级个VIP,相当于众筹了咱们下个月的研发经费;如果感觉囊中羞涩,每个月的收费提测来用,平时帮咱们打个小广告,就当交个敌人。就这样,咱们交到了越来越多的敌人,UWA的口碑和品牌开始逐渐在行业里累积了起来。 随后,咱们针对过后的外围产品:线上真人真机测试服务做了继续的优化:加了性能简报、行业排名、剖析倡议、优化队列,反对了iOS平台、PC平台、反对了IL2CPP版本... 这里分享一个数据:超过2000多我的项目在咱们平台上提测大于等于5次,并且均匀晋升了20%的性能。 很快,咱们累积了一批外围用户,他们是十分可恶的群体,大部分都十分敌对。在帮忙他们解决问题的过程中,不仅他们感触到了UWA的“有温度”,咱们UWA员工本人也感觉到真正地参加进这个我的项目中,一句“谢谢”都有种世间值得的满足。 从0.1到1:把优化市场做到一百米深如果维持过后的产品服务不去拓展,或者咱们能够轻松很多。但事实是:更多需要向你扑来的时候,你只会感觉本人的能力太局限了。咱们享受到了一些市场红利,但市场号召咱们去做更多有意义的事件。于是咱们开始了从0.1向1的迈进和摸索。 深刻到各大团队中,咱们发现,对于大部分团队来说,优化解决的是短期内的需要,但越是短期的需要,就越须要和工夫赛跑,这种需要的意义其实越低,所以咱们还须要更深刻地把握对于优化的更深层的货色,正如同咱们的一位开发敌人说的,比优化代码更重要的是优化思维,这就要与工夫成为敌人,缓缓积淀累积,工夫越长、价值越高。 过来的两年,咱们提出了性能保障体系,绝对于过来头疼医头脚疼医脚的优化形式,咱们倡议开发团队改善优化流程,随时发现问题、随时解决问题。咱们的产品体系也从刚开始仅有的真人真机测试倒退为残缺的性能品质保障体系,陆续推出了GPM、GOT Online、自动化测试和Pipeline等服务,在不同的研发阶段为开发者的优化之路构筑起多道防线。 在咱们前几年的UWA DAY大会上就有不少团队分享了他们的最佳实际: 喔,原来优化能够这样执行; 原来性能能够做到这样的水平; 甚至有公司会说,喔,原来咱们团队的组织架构能够更加正当... 从0到0.1,是优化性能问题; 从0.1到1, 是优化优化的流程。 从优化到保障,咱们实现了1。 所有的优化,实质上是人思维的扭转解决了产品的技术问题,咱们再来说下人的问题。因为纵然有不错的工具,实质上还是须要人的了解能力更好地执行:为什么要这么优化、实质的起因是什么、可能会有怎么的局限性、下次呈现雷同的问题,咱们是否也能相似地解决...所有的优化引起的提高,实质上都是思维的降级。 咱们所处的时代正在以前所未有的速度在向前一直推动,整个世界近30年来的变动甚至要比再之前300年来的变动还要大。每年甚至每月都会有大量的新技术、新教训不断涌现。常识在爆炸性地增长,但咱们的工夫却并没有减少。所以,无论是行业新人,还是技术牛人,咱们该如何去学习、吸取有用的常识来补充本人的常识体系,是咱们所有人都在面对的难题。 最近两年,咱们继续在UWA学堂上投入精力,初衷很简略,解决企业用人的问题。 问答、学堂、开源库和博客都隶属于常识服务的局部。 开源库帮忙大家更快捷、不便地找到须要的开源解决方案;问答解决的是具象的问题,寻找到更适合的解决答案;学堂旨在流传游戏行业的进阶学习内容,让常识共享有收益,让学习成长有体系;学堂训练营是UWA推出的技术晋升培训课,旨在流传零碎的实践和实用的技能,通过短期内高强度培训和实际,实现学以致用。过来,咱们UWA是常识的搬运工,而当初,咱们更多的是和开发者独特发明常识。常识服务是UWA策略倒退中极为要害的一环,在向指标一直靠近、一步一步实现的过程中,岂但能够促成游戏生态的一直改善,让开发者受害,也能让咱们本人在整个游戏产业中表演更重要的角色,承当更重要的责任。 举重若轻,源于长期保持“利他”二字守业的过程中少不了各种抉择、各种纠结,正如《创业维艰》这本书里写的:“只有3天是逆境,剩下8年全都举步维艰”。 **然而,有2个字能够让咱们举重若轻,那就是“利他”。UWA是一家天生有着To B基因的公司,咱们有着很强的“利他”精力,这就是咱们UWA的基因。 所谓基因,不是外表上所做的业务,而是外在的价值观和做事逻辑。** 当遇到一个超出咱们服务范畴的问题,咱们技术工程师不会间接Say No,而会说“兄弟,你先等等,你们这个我的项目工程过于奢华,咱们再钻研下看看怎么解决”;当遇到用户不分明该买咱们哪个服务的时候,咱们商务共事会说“你们问题次要集中在这里,你买咱们这个就能够了,没必要节约钱多买。就当咱们交给敌人”。 UWA置信,不论什么时代,为客户发明价值是指标,赚钱是后果和奖赏。优良的公司赚取利润,平凡的公司博得人心。 时值UWA五周年之际,UWA品牌形象更新,此次更新代表着UWA产品和服务的大众化、社区化。 浅色形象代表了开发者,与开办uwa4d.com时的愿景4d(for developer)相响应。UWA从成立起始终置信,只有开发者受害,咱们才受害。 往年产生了很多事,很多咱们不违心承受的事件。但宏观是咱们必须承受的,宏观才是咱们能够有所作为的。咱们十分荣幸且将继续成为整个行业后退的后驱车。 咱们将秉承UWA的价值观,保持长期主义,把一米宽的市场做到一百米深。 既往不恋,尽情向前。

August 19, 2020 · 1 min · jiezi

关于优化:发布-Optuna-20

公布 Optuna 2.0咱们很快乐公布 Optuna 的第二个次要版本,Optuna 是一个用 Python 写的的超参数优化(HPO)框架,当初你曾经能够通过 PyPI 和 conda-forge 来获取它。 自往年一月的第一个次要版本公布以来,咱们见证了社区在提出 pull request, issue 和一些不属于常见HPO的用例等方面做出的微小致力。而该框架也已倒退到能够包容大量的新性能,其中包含用于评估超参数重要性的个性,用以节俭计算资源的简单剪枝算法,以及与 LightGBM 的严密集成。本文将向你介绍这些更新,并展现本我的项目自上一个版本起的倒退过程。同时,咱们还将分享将来的布局,以期让你先一步理解将来会引入的新个性。。 如果你曾应用过 Optuna, 则能很快了解上面将介绍的内容。如果你想先理解对本框架,请参考咱们之前的博客(https://medium.com/optuna/optuna-v1-86192cd09be5),它解释了 Optuna 背地的各种概念。 新个性 超参数重要性性能晋升Hyperband Pruning新的 CMA-ES 采样与第三方框架的集成 (Integration)文档与 PyTorch 合作将来布局贡献者新个性上面介绍的是本次公布的版本中一些十分重要的个性。 超参数重要性尽管 Optuna 的设计能够解决任意多的超参数,但通常状况下,咱们倡议放弃尽量少的参数个数,以缩小搜寻空间的维度。因为实际上,在许多状况下,只有很少的参数在确定模型的整体性能中起主导作用。而从 2.0 版开始,咱们 引入了一个新模块 optuna.importance. 该模块能够评估每个超参数对整体性能的重要性,`optuna.importances.get_param_importances`. 该函数承受一个 study 作为参数,返回一个字典,该字典将不同的超参数映射到其各自的重要性数值上,这个数值的浮动范畴为 0.0 到 1.0, 值越高则越重要。同时,你也能够通过批改evaluator 参数来尝试不同的超参数重要性评估算法,其中包含 fANOVA,这是一种基于随机森林的简单算法。因为各种算法对重要性的评估形式不同,因而咱们打算在当前的发行版中减少可选算法的数量。 study.optimize(...)importances = optuna.importance.get_param_importances(study)# Specify which algorithm to use.importances.optuna.importance.get_param_importances( study, evaluator=optuna.importance.FanovaImportanceEvaluator())你不必本人解决这些重要性数据,Optuna 曾经提供了同 `optuna.importance.get_param_importances` 具备雷同接口的函数 `optuna.visualization.plot_param_importances`。它将返回一个 Plotly 图表,这对于可视化剖析很有帮忙。 fig = optuna.visualization.plot_param_importances(study) ...

August 14, 2020 · 2 min · jiezi