我的应用程序太慢了,现在怎么办?

我的应用程序太慢了,现在怎么办?
我的应用程式

在遇到性能问题之前,您不必长时间担任软件工程师。 数据库加载太慢。 计算路线需要花费很多时间。 远程呼叫挂起。 该怎么办?

SQL查询优化? JS包装? 指数? 算法优化? 多线程? 更改为C ++? 云? 微服务? 分片? NoSQL? 删除功能? 增加硬件要求? 内核优化? JIT正在加载? 负载均衡? 删除变量? 使用Protobuf? 压缩效果更好? 更改库? 改变框架? GC调整?

有很多方法可以加速代码,但并非所有方法都有效或值得努力。 但是您的情况下最好的选择是什么? 这是一个广阔的专业领域,例如,如果您碰巧需要上面列出的所有技术,那么他们都有自己的专家。 在您去雇用一个人之前,让我们完成一些可能有助于您做出决定的步骤。

步骤1:诊断

诊断问题是显而易见的第一步。 它可以与计时函数调用一样简单,但是无论使用何种平台,通常都最好启动分析器,例如Chrome Developer Tools Profiles窗格或Java Mission Control。 现在有很多性能分析工具 ,因此可以找到适合您需求的工具。 花一些时间来学习如何使用它,他们通常会很快将您找出最严重的犯罪者。

这也是发现编程错误(如内存泄漏)的好时机。 无论如何,这些都需要修复。 查找对象计数和分配的内存,看看数字是否有意义。

帕累托原理几乎可以肯定会保持不变-80%的缓慢性是由20%的代码引起的。 实际上,它通常比这要极端得多-单个经常命中的函数可能是整个100k行代码库的瓶颈,因此您的大部分工作应首先解决该问题。

通常,问题与解决方法一样明显,因此抓住这些悬而未决的水果可以解决您的大部分难题。 如果不清楚如何以及如何解决,请继续阅读。

步骤2:了解您的域名

我的应用程序太慢了,现在怎么办?
芬兰应征入伍者将于2017年测试投票系统。

即使可以做某事,也不意味着应该做。 在决定执行任何大动作之前,了解您的域,给定的硬件限制和预期的负载至关重要。 我们在这里谈论单人游戏吗? 在Raspberry Pi上运行的硬件传感器读取应用程序? 最多可容纳100位用户的商务应用? 一个拥有数百万并发用户的Web应用程序? 在Pi上将从Ruby更改为C可能有意义,但对于Rails应用而言可能没有意义。

让我们以芬兰议会及其投票制度问题为例:

芬兰议会在2000年代初升级了其电子投票系统。 在测试的最后阶段,他们发现,当足够多的成员同时按下投票按钮时,系统将无法处理负载并崩溃。

在芬兰议会中,主席要求对某事进行表决,您有200名议会议员通过按Jaa(是),Ei(否)或Tyhjää(以上都不是)中的三个选项对某事进行表决。 他们通常有大约10秒钟左右的时间来执行此操作。 因此,如果您考虑一下,最不常见的情况就是不起作用的情况-大多数成员将在投票结束时立即按下其按钮。

那么我们至少从性能上可以从中学到什么呢? 了解您的领域。 即使电子设备出现问题,即使后端有点慢,更改为无服务器云架构也可能无济于事。 将您的目标定为与现在和不久的将来的预期负荷相匹配。 无需使投票系统与10000个并发用户一起使用。 议会不会(我希望!)扩大到这样的规模。 实际上,将目标精确设置为200是可以的,也许会额外抛出20,以保证误差范围。

负载通常不是这种可预测的和静态的。 Reddit头版用户的数量激增和达到顶峰,这令人惊讶。 但是,仍然要了解您的竞争环境,并接受一次为所有事情做准备可能不值得。 如果您将Android应用的性能目标设置为最慢的手机,则将永远无法发货。 相信我,它比那个树懒慢。

如果您有一百个用户,并且希望达到一千个用户,那么现在应该采取的措施与从一千个增加到一百万个相比有所不同。 后者可能需要使用微服务之类的技术,它们会给系统增加巨大的复杂性,并增加风险。 达到一千个可能是优化数据库查询的问题。

步骤3:确定行动方案

因此,该应用程序运行缓慢,并且您已诊断出问题。 正是该功能从远程数据库加载数据。 那么,您应该如何进行呢?

以下是与领域无关的问卷,以缩小您的选择范围:

我可以完全跳过吗?

认真考虑一下。 甚至您的超优化算法也比我删除的代码慢。 许多最大的性能技巧(如自适应磁贴刷新)都是避免执行操作的核心方法。 考虑一下用例,如果它不是至关重要的话,也许您可​​以不用它,

也许它的一些轻量级版本就足够了? 您是否真的需要7MB js库来加载10MB的SVG公司徽标,该徽标对角为10个像素?

我可以把它搬到便宜一点的地方吗?

也许首页上有一个计算量很大的列表。 大家都用吗? 如果没有,也许将它移到某个地方,这样只会造成真正需要它的人。 它还可以节省后端的周期。

我只能做一次吗?

也称为缓存。 只做一次然后使用结果是有效的,但这也很困难 特别是如果您发明了自己的缓存方案,则会打开一大堆蠕虫来处理。 当呼叫突然返回过时的数据时,您现有的测试套件也可能不足以处理它。 被警告退步。 谨慎行事,最好使用ehcache等现有技术。

如果您的应用程序有很长的计算链,请考虑缓存中间结果。 如果您有内存,请使用它。

我可以部分做吗?

这可以像分页一样简单,也可以限制向用户显示的数据量,并在用户要求时请求更多数据。 另请参见JIT。

我可以索引它吗?

简化了索引,增加了数据结构,可加快数据检索速度。 如果您的数据库查询很慢,则SQL查询优化通常涉及添加索引。 但这可以是代码中添加的字典,用于存储可加快结果的键。 例如,如果您在地图上有一个城市图,则可以有一个额外的城市名称字典(索引),可用于检索节点。

维护索引的成本是高昂的,这通常意味着存储需求的增加和写入速度的降低。

我可以准时吗?

JIT(及时)意味着延迟数据的加载,直到真正需要它为止。 这可以是某种形式的延迟加载代码(对象在实际使用时即被初始化),也可以具有一个滚动列表,当用户向下滚动到该列表时,该列表可以加载更多元素,例如RecyclerView 几乎所有现代语言和框架都具有延迟加载的变体,因此请仔细研究。

我可以预载吗?

JIT的反面是预先加载块数据。 相对于较小的断断续续来说,只有一个较长的停顿时间是否可以忍受? 例如,如果硬件有限,则无法进行恒定加载,否则,如果UI是不可用的垃圾,那么一次长时间的等待可能是值得的。

我可以偷偷做吗?

启动画面。 每个人都喜欢闪屏吧? 嗯,这并不是那么秘密,但是当用户执行其他操作时在后台执行操作可能会把问题排除在外。 后台工作者 对此有好处。

缺点是同步-其他人需要计算结果吗? 这将不可避免地增加复杂性,并带来诸如死锁之类的有趣风险。

我可以同时做吗?

该野兽也称为多线程。 我可以将问题分成几部分,以便您可以并行解决它们,然后收集结果吗? 这可能非常有效,但是也很困难。 很难。

死锁,竞赛条件,Heisenbug,同步问题,线程安全,测试挑战。 如果您还不熟悉此功能,请回头。

我可以增加内存/ CPU吗?

有时,应用程序本身没有什么问题,只是资源不足。 如果操作系统用尽了内存并进行了交换,那将是有害的。 CPU周期也是如此。 如果应用程序不泄漏内存,则添加内存可能是解决问题的最便宜的选择。 如果您知道问题出在哪里,那么要做很多优化操作系统的工作。

例如,对于Web应用程序,您还可以将负载拆分到多台计算机上,并使用负载均衡器。 在云计算时代,这还可以像魔术一样扩展,您基本上什么都不做(但要付费)。

我可以猜猜吗?

缓冲..视频是最明显的示例,或者说是Specter err ..我的意思是CPU体系结构中的分支预测。 秘密地做事和尝试猜测用户接下来将要做什么的组合。

如果您猜错了,则会浪费周期(或创建安全漏洞)。

我可以容忍错误吗?

解决任何NP难题的可行解决方案。 如果足够好,但是尝试更快地解决方案可以使您达到最优值的2%,那么尝试完美地解决它可能是愚蠢的事。

对于非常大的数据集,NoSQL数据库的最终一致性也是一个例子。 乐观并在以后修复错误可以显着提高性能。

我可以优化算法吗?

在算法级别上从来没有做过很多事情。 例如,查看Java中Collection接口的已知子类。 您还记得所有这些内容,并且知道何时使用它们吗? 还是您的应用中的所有内容都是ArrayList 最重要的是,如果您确实需要推动它,则可以使用诸如fastutil之类的东西。 HashMap可以工作时,看到代码不必要地一遍又一遍地执行相同的操作并遍历一长串列表并不少见。

在代码级别有很多工作要做,如果您的单元测试是可靠的,那么它也应该相对安全。 再次,YMMV。

我可以减少请求吗?

从远程服务器获取数据很慢,与您的计算机内存相比非常慢。 到数据中心的往返速度比到RAM的速度慢100000倍。 如果您有很多往返行程,例如可以提出一个较大的批处理请求吗?

批处理的缺点是,如果批处理模块等待更多数据或请求中的大小因素,则单个请求的往返时间会增加。 YMMV。

我可以使用专用的文本搜索服务吗?

您的应用程序内部的文本搜索是否很慢? 如果您有足够的记忆力,像Lucene这样的事情可能会感觉像是黑魔法。 如果有足够的内存,请使用它们。

我可以将数据库分成更多可管理的块吗?

也称为分片 如果您的数据库已经发展到巨大的规模,那么也许可以选择。 它带有增加复杂性的警告。

我可以压缩吗?

我可以使用webpack之类的东西来最小化Web应用程序中的请求负载吗? 还是在大型网络传输中使用zip压缩? 如果您确定REST JSON开销过多,还可以研究协议缓冲区之类的内容。

我可以更改框架或编程语言吗?

不知道可以吗 这有帮助吗? 除非您使用的是Pi或类似的受限硬件,否则它应位于列表的底部。

我可以运行无服务器吗?

它解决了所有这些问题,所有很酷的孩子都做到了,所以我们也应该吧? 也许。 我没有这方面的经验,请告诉我如果您这样做的话!

还有什么?

有时问题更加棘手-仅在较重的负载难以复制时才存在,或者仅在看起来与其他设备相同的受格林姆林蛋白感染的计算机上仍然存在。 或者您只是用尽了显而易见的东西来进行优化。 这种类型的东西可以变得非常专业,您可以通过聘请专家找出来来节省时间。 诸如火焰图之类的操作可以帮助可视化疼痛区域。

无论您决定做什么,请确保已进行适当的测试,以验证更改是否有效并且不会引起回归。 即使外部没有任何变化,这些技术中的许多技术也可以真正显着地改变内部结构。 逐步更改,如果可能,一次进行一次优化。

祝好运!

我的应用程序太慢了,现在怎么办?
(不是)我的应用

From: https://hackernoon.com/my-app-is-too-slow-now-what-44d9791c3736