Brick mover: Why is the program always so slow? What the hell is it doing now? Where does the time go?


Interviewer: What about Java performance optimization?

1. String processing optimization is the source of optimization.

During development, the String API is probably used the most, creating strings and splitting strings is common.

1.1. Who is better at string splitting?

What are the common ways of string segmentation? Which way is better?

Method one, the split() method provided by String is often used to satisfy business needs.

The code simulates some data, and the program runs, taking about 3,000 milliseconds.

Method two: StringTokenizer, a utility class for string splitting.



Using a StringTokenizer to do the same data split() takes about 500 milliseconds.

At runtime, StringTokenizer is more efficient than the split() method. So, use StringTokenizer for string splitting wherever you can.

In addition, in normal development, it is necessary to pay attention to one point, when using the index to access the array obtained by the String split() method, it is necessary to do the content check after the last delimiter, otherwise there will be the risk of throwing exceptions.



1.2. String concatenation, which method is better?

Method 1: Concatenate the string with a + sign.

It took about 27,687 milliseconds for the program to run.

Method two uses StringBuilder to concatenate strings.

It takes about 24 milliseconds for the program to run.

Using the + sign to concatenate strings is obviously inefficient. Using StringBuilder to concatenate strings performs better. Similarly, if thread safety is a concern, StringBuffer can be used.

In addition, ali development manual also strongly recommends using StringBuilder append method to extend string concatenation in the loop body. If + sign concatenation is used, memory resources are wasted.

2. Make arrayCopy () easy to copy.

Array copy is the development process, the use of more functions, JDK provides an API to achieve. But which way is better?

One, as a developer, you like to build wheels, and that’s how the code will be written.



System.arrayCopy () is used to copy the array.



System. Arraycopy () does a little better when the data is large.

Arrays.copyof () is used to copy Arrays.

Since array.copyof () is still called system.arrayCopy (), the performance is definitely not as good as system.arrayCopy ().

Therefore, if you can use system.arrayCopy (), you are advised to use it.

3. Focus on circulation and don’t reinvent the wheel.

Make your program do as few repetitions as possible, especially the code inside the loop.

For a simple example, in the above code segment, math.pi * math.sin (k) is executed repeatedly in the body of the loop, and the result is unique, so consider taking it outside the loop.

The former takes about 30 milliseconds to validate on the native machine, and the adjustment takes about 2 milliseconds, which is still a performance improvement.

Therefore, extracting repetitive code from the body of the loop can effectively improve system performance.

In addition, ali development manual strongly recommends that statements in the loop body should consider performance, and the following operations should be moved to the outside of the loop as far as possible, such as defining objects, variables, obtaining database connections, and performing unnecessary try-catch operations (whether the try-catch can be moved to the outside of the loop).

4. Set more, use scenarios to pay attention to.

The collection family API is used quite frequently in business development. Then, the best program optimization is to fully choose a good data structure for data storage.

In order to more clearly describe the use of the respective scenarios, but also to better help you master, comb into a mind map.

4.1. In the List family, who is favored?



4.2. Who comes first in the Map family?

Also, when the collection is initialized, the collection initial value size is specified.

Note: HashMap is initialized using HashMap(int initialCapacity).


InitialCapacity = (Number of elements to be stored/load factor) + 1.

Note that the default load factor is 0.75. If you cannot determine the initial value, set it to 16(the default value).


Counterexample: A HashMap requires 1024 elements. As the initial capacity is not set, the capacity is expanded seven times as the number of elements continues to increase. Resize requires the reconstruction of the hash table, which severely affects the performance.


— Ali Development Manual


4.2. In the Set family, who is the best fit?

The commonly used data structures have been listed in the figure, so there is no need to write code to verify each one. Again, choosing the right data structure to store data is the best program optimization.

5. Cushion and let the bullet fly for a while.

Buffering, the most common scenario is to improve I/O speed and solve I/O performance bottlenecks. Buffering is provided for many I/O components in Java.

For example, using FileWriter to write data to a file.



It took about 8212 milliseconds for the program to run. So, what happens when you add buffering?

When the program ran, it took about 4,143 milliseconds and doubled its performance.

Therefore, buffer streams are used for file read and write operations to improve performance.

6. Caching, allowing people in planes to deal with people in donkey carts.

In the actual project research and development, cache is often used, cache is to improve the system performance and open up memory space.

The simplest caches can be implemented directly using a HashMap, where the application’s configuration information, for example, is loaded at startup.

Some frequently used business data, such as bank code, or hard-won calculation results can be saved in the cache. When used again, they can be directly obtained from the cache without occupying valuable system resources.

There are many Java-based caching frameworks out there, and the one I use the most is EhCache.

7. Keep a good journal and have no worries online.

Recommended: Log carefully. Debug logs cannot be generated in the production environment. Selectively output info logs; If warn is used to record service behavior information when the logs are first launched, be careful about the output of logs to avoid overloading server disks, and delete these logs in time.


Note: A large number of invalid logs are generated, which is not conducive to system performance improvement or fault location.

When journaling, think: Is anyone really reading these journals? What can you do with this log? Does it benefit troubleshooting?


— Ali Development Manual

8. Miscellaneous miscellaneous 8, a wordy sentence is not too much.

A rule of optimization: implement the business function first, then optimize the performance, if the function is not implemented, the rest is useless.

An idea for tuning:

  • First, at the system design level, see if there are improvements that can be made, whether there are design patterns that can be introduced, whether there are caching mechanisms that can be introduced, etc., to mask potential performance problems.

  • Then at the code level, see if the code can be optimized.

  • Then take a look at the environment in which your Java program is running, and tweak the JVM parameters to improve performance.

  • Then go to the database level to see if tuning is possible.

  • Finally, go to the operating system level to see if you can tune it.



Finally, this time to share here, I hope you can like, if you think the article is a little help to you, please search wechat “a little ape talk” first time to read.