In reality, there may be no perfect code. If so, then, come here, I’ll write a code to show you.

Java has become the darling of programming languages. Java technology has the remarkable versatility, high efficiency, portability and security platform, widely used in PC, data center, game consoles, science super computers, mobile phones and the Internet, more and more companies in the data structure and algorithm analysis, the research design such as software development, are chosen to Java language as a carrier. This shows that the Java language has become the primary language that people use when building software systems. Making Java programs run is one thing, making them run fast is another…

Here I’ve compiled some tips for Java performance tuning, and I’m going to talk to you briefly.

The importance of Java performance tuning:

Code optimization, a very important topic. Some people may feel useless, some small places have what to modify, change or not to change the efficiency of the code what impact? I think about it this way, like the whale in the sea, it eat a small shrimp useful? It didn’t work, but after eating more shrimp, the whale was full.

Code optimization is the same, if the project is aimed at bug-free online as soon as possible, then you can focus on the small, the details of the code can not be fine grinding; However, if there is enough time to develop and maintain the code, it is necessary to consider every detail that can be optimized. The accumulation of a small optimization point will definitely improve the running efficiency of the code.

The goals of code optimization are:

Reduce the size of the code

Improve the efficiency of code execution

Before we share Java-based performance tuning tips, let’s discuss these general performance tuning tips.

Four practical tips for general performance tuning

1. Don’t optimize until you have to

This is probably one of the most important performance tuning techniques. You should follow common best practices and try to implement your use cases effectively. But that doesn’t mean replacing any standard libraries or building complex optimizations before proving it’s necessary.

In most cases, premature optimization takes up a lot of time, making code difficult to read and maintain. Worse, these optimizations usually don’t do any good because you spend a lot of time optimizing non-critical parts of your application.

So how do you justify that you need to optimize something?

First, you need to determine the speed of your application code, for example, by specifying a maximum response time for all API calls, or by specifying the number of records to import within a specific time range. Once you’re done, you can measure which parts of your application are slow and need improvement. When you have done so, move on to the second tuning technique.

2. Use profilers to find the real bottleneck

After you’ve followed the first piece of advice and determined that some parts of your application really need improvement, ask yourself where to start.

You can solve this problem in two ways:

You can take a look at your code and start with the parts that look suspicious or that you think might cause problems.

Or use profilers to get detailed information about the behavior and performance of each part of the code.

As to why the second approach should always be followed.

The answer should be obvious: a profiler-based approach gives you a better understanding of the performance implications of your code and allows you to focus on the most critical parts. If you’ve ever used profilers, you’ll be surprised at what parts of your code are causing performance problems. Many times, however, your first guess will lead you in the wrong direction.

3. Create a performance test suite for the entire application

This is another general technique to help you avoid many of the unexpected problems that often occur after performance improvements are deployed to production. You should always define a performance test suite that tests the entire application and run it before and after you complete performance improvements.

These additional test runs will help you identify the functional and performance impact of the changes and ensure that you don’t release an update that will do more harm than good. This is especially important if your tasks are running in different parts of your application such as databases or caches.

4. Fix the biggest bottlenecks first

After you’ve created the test suite and analyzed the application using a profiler, you have a list of questions to improve performance, which is great, but it still doesn’t answer the question of where you should start. You can start with those that can be solved quickly, or you can start with the most important problems.

The former is tempting, of course, because it can be done quickly. Sometimes, it may be necessary to convince other team members or your management that performance analysis is worthwhile.

But in general, I recommend dealing with the most important performance issues first. This will give you the greatest performance improvement, and you may only need to fix a few of these issues to address your performance needs.

With general performance tuning tips in mind, let’s take a closer look at some Java-specific tuning tips.

Five tips for Java performance tuning

1. Use StringBuilder

You should consider this in almost any Java code. Avoid the + sign. You might think that StringBuilder is just syntax candy, for example:

String x = “a” + args.length + “b”;

Will be compiled into

But then you need to modify the string based on the condition, what happens?

You will now have a second StringBuilder that doesn’t need to exist, which will consume heap memory and burden the GC. You should write:

2. Avoid regular expressions

Regular expressions are relatively cheap and convenient. But if you’re in the N.O.P.E. branch, that’s bad. If you must use regular expressions in computer-intensive code segments, at least cache references to Pattern to avoid recompiling them every time:

static final Pattern HEAVY_REGEX =

Pattern.compile(“(((X)*Y)*Z)*”);

But if your regular expression is really simple, like

String[] parts = ipAddress.split(“//.”);

Then you’d really be better off resorting to plain char[] or index-based operations. For example, the following code does the same thing:

This also shows why you shouldn’t optimize too early. Compared to the split() version, this is simply unmaintainable.

Regular expressions are useful, but they come at a cost. If you branch in N.O.P.E, you must avoid the cost of regular expressions.

3. Never use iterator()

This advice doesn’t apply to regular use cases, only to the N.O.P.E. branch, but you can use it. Writing java-5-style foreach loops is convenient. You can ignore the inner loop variables completely and write:

for (String value : strings) {

// Do something useful here}

However, whenever you run inside the loop, if the string is an Iterable, you need to create a new instance of Iterator. If you are using ArrayList, this will allocate an object with three ints on the heap:

private class Itr implements Iterator<E> {

int cursor;

int lastRet = -1;

int expectedModCount = modCount;

/ /…

Instead, you can write code that is equivalent to the body of the loop and “wastes” only one int on the stack, with low overhead:

int size = strings.size(); for (int i = 0; i < size; i++) {

String value : strings.get(i);

// Do something useful here}

… Alternatively, you can choose not to change the linked list and use the same operation on the array version:

for (String value : stringArray) {

// Do something useful here}

The key point

Iterators, Iterable, and foreach loops are useful both from a writability and readability perspective and from an API design perspective. But they create a small new instance on the heap for each individual iteration. If you run the iteration many times and want to avoid creating a useless instance, you can use index-based iteration.

4. Do not call these methods

Some methods are simple but expensive. In the N.O.P.E. branch example, we didn’t use this method on leaves, but you probably did. We assume that the JDBC driver needs a lot of resources to compute the resultSet.wasNULL () value. You might develop SQL frameworks with the following code:

if (type == Integer.class) {

result = (T) wasNull(rs,

Integer.valueOf(rs.getInt(index)));

}

/ / And then… static final <T> T wasNull(ResultSet rs, T value) throws SQLException {

return rs.wasNull() ? null : value;

}

The logic here calls resultset.wasnull () every time you get an int from the ResultSet. But the convention for getInt() is:

Returns: number of columns; If the value is SQL NULL, the value will return 0.

Thus, a simple but potentially effective improvement to the above problem would be:

static final <T extends Number> T wasNull(

ResultSet rs, T value

) throws SQLException {

return (value == null ||

(value.intValue() == 0 && rs.wasNull()))

? null : value;

}

Therefore, there is no need to think too much about it.

The key point

Do not call an expensive method in the “leaf node” of the algorithm, but cache the call or avoid it if the method specification allows it.

5. Use primitive types and stacks

The examples above make heavy use of generics. Generics enforce the boxing of byte, short, int, and long types — at least until then: Generics are specialized in Java 10 and Valhalla projects. Now your code doesn’t implement this constraint, so you need to do something about it:

// Goes to the heapInteger i = 817598;

… Replace this with the following:

// Stays on the stackint i = 817598;

Not so good if you use arrays:

// Three heap objects! Integer[] i = { 1337, 424242 };

… Replace it with this:

// One heap http:// object.int[] i = { 1337, 424242 };

The key point

Be careful with boxing types as you go deeper into the N.O.P.E. branch. You may put a lot of pressure on GC to clean up your mess all the time.

A particularly effective way to optimize this is to take some basic types and create a large one-dimensional array for it, with positioning variables that specify exactly where the encoded object is placed in the array.

The LGPL-licensed Trove4J library implements a collection of basic data types that look better than int[].

Conclusion:

As you can see, improving application performance sometimes doesn’t require a lot of work. Most of the suggestions in this article can be applied to code with little effort.