课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
我们在完成网页设计和软件开发项目之后,为了能够提高我们的产品运行速度和结构的调整,通常都需要对编程代码进行优化。而许多的工程师认为代码优化是一件很繁琐的事情。
下面,我们就给大家分享几点能够在代码优化过程中提高效果的几个技巧。
1.在明确必要之前别急着优化
这可能是最重要的性能优化技巧之一。你应该遵循常见的最佳实践做法并在案例中高效地应用它。但是这并不意味在证明必要之前,你应该更换任何标准库或构建复杂的优化。
多数情况下,过早地优化会占用大量的时间,而且会使代码变得难以理解和阅读。更糟糕的是,这些优化通常并没带来任何好处,因为你花了大量的时间在优化应用中的非关键部分。
那么,要怎么证明东西需要优化呢?
首先,你需要定义你的代码速度得多快。例如,为所有API调用指定最大响应时间,或者指定在特定时间范围内要导入的记录数量。在做完这些后,你需要确定你应用中哪些部分太慢需要改进。当完成这些后,你就可以来看看第二个技巧提示。
2.使用分析器找到真正的瓶颈
在完成第一部分的优化建议以鉴别出你应用中需要提升的部分后,要从哪里入手呢?
你可以有两种途径来解决这个问题:
查看你的代码,从看起来可疑的或者你觉得可能会导致出现问题的地方入手。
或者使用分析器获取代码每个部分的行为(执行过程)和性能的详细信息。
希望我不需要解释为什么应该始终遵循第二种途径/方法的原因。
很显然,基于分析器的方式可以让你更好地理解代码的性能影响,并允许你去专注于更关键的部分(代码)。即使你曾经使用过分析器,你一定记得你曾经多么惊讶于一下就找到了代码的哪些部分产生了性能问题。我第一次的猜测不止一次地导致我走错了方向。
3.为整个应用程序创建一个性能测试套件
这是另一个通用的可以帮助你避免在将性能改进部署到产品中之后经常会发生的许多意外问题的技巧。你应该总是定义一个性能测试套件来测试整个应用程序,并在性能改进之前和之后运行它。
这些额外的测试运行将帮助你识别你的改动所引起的功能和性能上的副作用,并确保不会导致弊大于利的更新。如果你处理的是被应用程序的多个不同部分使用的组件,如数据库或缓存,那这一点尤为重要。
4.优先关注最大瓶颈
在创建了测试套件并使用分析器分析你的应用程序之后,你可以列出一系列需要解决以提高性能的问题列表。这很好,但这并没有回答你需要从哪里开始的问题。你可以专注于速成方案,或从最重要的问题开始。
速成方案一开始可能会很有吸引力,因为你可以很快显示第一个成果。但有时,可能有必要说服其他团队成员或管理层认为性能分析是值得的。
一般来说,我建议从顶层开始,首先开始处理最重要的性能问题。这将为你提供最大的性能改进,而且你可能仅需要解决这些问题中的一小部分就能满足你的性能要求。
常见的通用调优技巧到此结束。接下来让我们仔细看看一些特定于Java的技巧。
5.使用StringBuilder以编程方式连接字符串
在Java中有很多不同的选项来连接字符串。例如,你可以使用简单的+或+=,以及老的StringBuffer或StringBuilder。
那么,你应该选择哪种方法呢?
答案取决于连接字符串的代码。如果你是以编程方式将新内容添加到字符串中,例如在for循环中,则应使用StringBuilder。它很易于使用,并提供比StringBuffer更好的性能。但请记住,与StringBuffer相比,StringBuilder不是线程安全的,可能并不适用于所有情况。
你只需要实例化一个新的StringBuilder并调用append方法来向String中添加一个新的部分。在你添加完了所有的部分后,你可以调用toString()方法来检索已连接的字符串。
6.使用+连接一个语句中的字符串
当你使用Java实现你的第一个应用程序时,可能有人告诉过你不要使用+来连接字符串。如果你是在应用程序逻辑内连接字符串的话,这是对的。字符串是不可变的,每个字符串的连接结果都被存储在一个新的字符串对象中。这需要额外的存储空间,并可能使你的应用程序运行缓慢,特别是当你在一个循环内连接多个字符串的情况下。
在这些情况下,你应该遵循技巧5中的内容,并使用StringBuilder。
但如果你只是将字符串分成多行来改善代码的可读性,这并不适用。
7.尽可能使用基本类型
避免任何开销并提高应用程序性能的另一种简便快速的方法是使用基本类型而不是其包装类。所以,最好使用int而不是Integer,是double而不是Double。这将使得你的JVM将值存储在堆栈而不是堆中,以减少内存消耗,并更有效地处理它。
8.尽量避免大整数和小数
由于我们已经在讨论数据类型,所以我们也应该快速浏览大整数和小数。尤其是后者因其精确性而受欢迎。但这是有代价的。
大整数和小数比一个简单的long型或double型需要更多的内存,并会显著减慢所有的运算。所以,如果你需要额外的精度,或者如果你的数字超出一个较长的范围,最好要三思。这可能是你需要更改并解决性能问题的唯一方法,尤其是在实现数学算法时。
9.优先检查当前日志级别
这个建议应该是显而易见的,但不幸的是,很多人在写代码的时候都会忽略它。在创建调试消息之前,应该总是优先检查当前日志级别。否则,你可能会创建一个附加你日志消息的字符串,而该字符串之后将被忽略。
10.使用ApacheCommonsStringUtils.Replace而不是String.replace
一般来说,String.replace方法可以正常工作,并且效率很高,尤其是在你使用Java9的情况下。但是,如果你的应用程序需要大量的替换操作,并且没有更新到最新的Java版本,那么检查更快和更有效的替代品依然是有必要的。
有一种候选方案是ApacheCommonsLang的StringUtils.replace方法。正如LukasEder在他最近的一篇博客文章中所描述的,它远远胜过了Java8的String.replace方法。
而且它只需要很小的改动。你只需要将ApacheCommonsLang项目的Maven依赖项添加到你的应用程序的pom.xml中,并将String.replacemethod的所有调用替换为StringUtils.replace方法。
11.昂贵的缓存资源,如数据库连接
缓存是避免重复执行昂贵或常用代码片段的流行解决方案。总的思路很简单:重复使用这些资源比创建一个新的资源更划算。
一个典型的例子是缓存池中的数据库连接。新连接的创建需要时间,如果你重用现有连接,则可以避免这种情况。
你也可以在Java语言源码中找到其他的例子。例如,在Integer类中的valueOf方法缓存了介于-128到127之间的值。你可能会说创建一个新的Integer并不是太昂贵,但是由于它经常被使用,因此缓存最常用的值也可以提供性能优势。
但是,当你考虑使用缓存时,请记住缓存实现也会产生开销。你需要花费额外的内存来储存可重复使用的资源,因此你可能需要管理你的缓存以使资源可访问,并删除过期的资源。
所以,在开始缓存任何资源之前,请确保它们是经常使用的,以超过缓存实现的开销(代价)。
译者:Tocy,Tot_ziens,Tony,透过树叶的光,我是菜鸟我骄傲
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!