在处理任何Java应用程序时,我们都会遇到优化的概念。我们编写的代码不仅要干净、没有缺陷,而且要经过优化,即代码执行所花费的时间应该在预期的范围内。为了实现这一点,我们需要参考Java编码标准并检查我们的代码以确保它符合标准。
但有时由于截止日期的限制,我们没有时间实际审查代码。在这种情况下,我们提供了一些技巧,开发人员在对任何需求进行编码时可以牢记这些技巧,以便他/她在测试阶段或将其移至生产之前需要对代码进行最少的更改以修复性能。
1. 避免编写长方法
这些方法不应太长,并且应该专门用于执行单个功能。由于在类加载和方法调用期间,方法被加载到堆栈内存中,因此对于维护和性能来说更好。如果方法很大且处理过多,它将消耗内存和 CPU 周期来执行。尝试在合适的逻辑点将方法分解为更小的方法。
2.避免多个 If-else 语句
我们在代码中使用条件语句进行决策。不应过度使用条件语句。如果我们使用太多条件 if-else 语句,它会影响性能,因为JVM将不得不比较条件。如果在 for、while 等循环语句中使用相同的语句,情况会变得更糟。如果您的业务逻辑中有太多条件,请尝试将条件分组并获取布尔结果并在 if 语句中使用它。此外,如果可能,我们可以考虑使用 switch 语句而不是多个 if-else。与 if – else 相比,switch 语句具有性能优势。下面提供的示例作为说明,应避免如下:
插图:
if (condition1) {
if (condition2) {
if (condition3 || condition4) { execute ..}
else { execute..}
Note: Above sample is to be avoided and use this as follows:
boolean result = (condition1 && condition2) && (condition3 || condition4)
3.避免在循环中获取集合的大小
在迭代任何集合时,事先获取集合的大小,并且在迭代期间永远不会获取它。下面提供的示例作为说明,应避免如下:
插图:
List objList = getData();
for (int i = 0; i < objList.size(); i++) { execute code ..}
Note: Above sample is to be avoided and use this as follows:
4. 避免使用字符串对象进行连接
String 是一个不可变类,String 创建的对象不能被重用。因此,如果我们需要在 SQL 查询等情况下创建一个大字符串,那么使用 ‘+’运算符连接 String 对象是不好的做法。这将导致创建多个 String 对象,从而导致更多的堆内存使用。在这种情况下,我们可以使用 StringBuilder 或 StringBuffer,前者优先于后者,因为它由于非同步方法而具有性能优势。下面提供的示例作为说明,应避免如下:
插图:
List objList = getData();
int size = objList.size();
for (int i = 0; i < size; i++) { execute code ..}
Note: Above sample is to be avoided and use this as follows:
StringBuilder strBuilder = new StringBuilder(“”);
strBuilder.append(String1).append(String2).append(String3);
String query = strBuilder.toString();
5. 尽可能使用原始类型
在对象上使用原始类型是有益的,因为原始类型数据存储在堆栈内存中,而对象存储在堆内存中。如果可能,我们可以使用原始类型而不是对象,因为从堆栈内存访问数据比堆内存快。所以在整数上使用 int 或在 Double 上使用 double 总是有益的。
6. 避免使用 BigDecimal 类
我们知道 BigDecimal 类为十进制值提供了准确的精度。过度使用此对象会严重影响性能,特别是当它用于计算循环中的某些值时。 BigDecimal 在 long 或 double 上使用大量内存来执行计算。如果精度不是约束条件,或者如果我们确定计算值的范围不会超过 long 或 double,我们可以避免使用 BigDecimal 并使用 long 或 double 进行适当的转换。
7. 避免经常创建大对象
有某些类在应用程序中充当数据持有者。这些对象很重,应避免多次创建它们。此类对象的一个示例是用户登录后的 DB 连接对象或系统配置对象或会话对象。这些对象在创建时使用了大量资源。我们应该重用这些对象而不是创建,因为创建会因为更多的内存使用而极大地阻碍应用程序的性能。我们应该尽可能使用单例模式来创建对象的单个实例并在任何需要的地方重用它,或者克隆该对象而不是创建一个新的对象。
8.使用存储过程代替查询
最好编写存储过程而不是复杂和冗长的查询,并在处理时调用它们。存储过程作为对象存储在数据库中并经过预编译。与具有相同业务逻辑的查询相比,存储过程的执行时间更少,因为每次通过应用程序调用查询时,都会编译和执行查询。此外,存储过程在数据传输和网络流量方面具有优势,因为我们不会每次都将复杂的查询传输到数据库服务器上执行。
9. 使用 PreparedStatement 而不是 Statement
在通过应用程序执行 SQL 查询时,我们使用 JDBC API 和类。 PreparedStatement 在参数化查询执行方面优于 Statement ,因为 PreparedStatement 对象编译一次并执行多次。另一方面,语句对象每次被调用时都会被编译和执行。此外, preparedstatement 对象是安全的,可以避免 Web 应用程序安全的 SQL 注入攻击。
10. 使用不必要的日志语句和错误的日志级别
日志记录是任何应用程序不可或缺的一部分,需要有效实施以避免由于错误的日志记录和日志级别而导致性能下降。我们应该避免将大对象记录到代码中。日志记录应仅限于我们需要监控的特定参数,而不是整个对象。此外,日志记录级别应保持在更高级别,例如 DEBUG、ERROR,而不是 INFO。下面提供的示例作为说明,应避免如下:
插图:
String query = String1+String2+String3;
Note: Above sample is to be avoided and use this as follows:
Logger.debug(“User info : ” + user.getName() + ” : login ID : ” + user.getLoginId());
Logger.info(“Method called for setting user data”);
11.在查询中选择所需的列
从数据库中获取数据时,我们使用选择查询来获取数据。避免选择不需要进一步处理的列。仅选择我们需要进一步处理或在前端显示的那些列。选择太多列会导致数据库端查询执行延迟。此外,它会增加从数据库到应用程序的网络流量,这是应该避免的。下面提供的示例作为说明,应避免如下:
插图:
Logger.debug("User info : " + user.toString());
Logger.info("Method called for setting user data:" + user.getData());
Note: Above sample is to be avoided and use this as follows:
select user_name, user_age, user_gender, user_occupation, user_address from users where user_id = 100;
12.使用连接获取数据
从多个表中获取数据时,有必要在表上正确使用连接。如果未正确使用连接或表未规范化,则会导致查询执行延迟,从而导致应用程序性能下降。避免使用子查询而不是连接,因为子查询比连接花费更多时间来执行。在表的列上创建索引,这些列经常用于提高查询执行的性能并减少应用程序的延迟。