three. Optimize the Java program design and encoding, improve some of the methods of Java program performance.
Find the bottleneck in the program by using some of the previously described auxiliary tools, and then optimize the code of the bottleneck portion. There are generally two options: optimizing code or changing design methods. We generally choose the latter, because you don't call the following code to improve program performance than call some optimized code. And a well-designed program can streamline the code to improve performance.
Some methods and techniques that are often used in the design and encoding of the Java program, and some methods and techniques that are often used in the design and encoding of the Java program.
1. Adjustment of the generation and size of the object.
A common problem in the Java program is that there is no function provided by the Java language itself, which often generates a large number of objects (or instances). Since the system not only takes time to generate an object, it may still take time to take the time to garbage recycling and processing. Therefore, excessive objects will have a big impact on the performance of the program.
Example 1: About String, StringBuffer, and Append
The Java language provides operations for String type variables. However, if not used, it will affect the performance of the program. As of the following statement:
String name = new string ("HuangWeifeng");
System.out.println (Name "Is My Name");
It seems that it is very streamlined, it is not the case. In order to generate binary code, the following steps and operations are processed.
(1) Generate a new string new string (STR_1);
(2) Copy the string.
(3) Load the string "HuangWeifeng" (STR_2);
(4) Arrival (constructor) of the string;
(5) Save the string to the array (starting from position 0)
(6) Get static OUT variables from java.io.printStream class
(7) Generate a new string buffer variable new stringbuffer (str_buf_1);
(8) Copy the string buffer variable
(9) Call structor;
(10) Save the string buffer to the array (starting from position 1)
(11) The APPEND method in the string buffer class is called in STR_1.
(12) Loading a string constant "is my name" (STR_3);
(13) The APPEND method in the string buffer class is called in STR_3.
(14) Execute the toString command for STR_BUF_1.
(15) Call the PrintLn method in the OUT variable, output the result.
It can be seen that the two lines of simple code generates STR_1, STR_2, STR_3, STR_4, and STR_BUF_1 five object variables. Examples of these generated classes are generally stored in the heap. Piles are initialized for all classes, classes of all classes, while also calling an extremely super-class architecture. These operations are very consumed system resources. Therefore, it is necessary to limit the generation of objects.
After modification, the above code can be replaced with the following code.
StringBuffer name = new stringbuffer; system.out.println ("is my name."). TOSTRING ());
The system will perform the following operations.
(1) Generate a new string buffer variable new stringbuffer (str_buf_1);
(2) Copy the string buffer variable
(3) Load string often "huangweifeng" (STR_1);
(4) Call the string buffer architecture (constructor);
(5) Save the string buffer to an array (starting from position 1)
(6) Get static OUT variables from java.io.printStream class
(7) Load STR_BUF_1;
(8) Load string constant "is my name" (STR_2);
(9) The Append method in the string buffer instance is called in STR_2.
(10) Execute the toString command for STR_BUF_1. (STR_3)
(11) Call the PrintLn method in the OUT variable and output the result.
It can be seen that the improved code only generates four object variables: STR_1, STR_2, STR_3 and STR_BUF_1. You may feel that less generation of an object will not increase the performance of the program. However, the execution speed of the code segment 2 below will be twice the code segment 1. Since the code segment 1 generates eight objects, the code segment 2 generates only four objects.
Code segment 1:
String name = new stringbuffer ("huangweifeng");
Name = "is my";
Name = "Name";
Code segment 2:
StringBuffer name = new stringbuffer ("HuangWeifeng");
Name.Append ("is my");
Name.append ("name."). TOSTRING ();
Therefore, fully utilizing the library function provided by Java to optimize the program, which is very important to improve the performance of the Java program. The attention points mainly have the following aspects;
(1) Use Static Class Variables as possible
If the variables in the class do not change with his instance, you can define a static variable so that all the instances share this variable.
example:
Public Class Foo
{
SomeObject so = new homeObject ();
}
It can be defined as:
Public Class Foo
{
Static SomeObject SO = New SomeObject ();
}
(2) Do not change too much of the generated object.
For some classes (such as: String class), prefer to regenerate a new object instance without modifying the generated object instance.
example:
String name = "huang";
Name = "wei";
Name = "feng";
The above code generates three String type object instances. The first two immediately need system for garbage collection. If you want to connect to a string, performance will be worse. Because the system will not generate more temporary variables for this. As shown in the first example.
(3) When the object is generated, it is assigned to it to reasonably space and the size.
Many classes in Java have its default spatial allocation size. For StringBuffer classes, the default assignment space size is 16 characters. If the size of the StringBuffer is not 16 characters in the program, the correct initialization must be performed.
(4) Avoid generating objects or variables shorter or shorter life cycle. For this case, an object buffer pool is defined. It is to manage a smaller cost of managing a target buffer pool than frequent generation and recycling objects.
(5) Initialization only within the target scope.
Java allows you to define and initialize the object anywhere in your code. In this way, it can be initialized only within the range of the object. Thereby saving the overhead of the system.
example:
SomeObject so = new homeObject ();
IF (x == 1) THEN
{
FOO = sol .getxx ();
}
Can be modified to:
IF (x == 1) THEN
{
SomeObject so = new homeObject ();
FOO = sol .getxx ();
}
2. Excetions
Try / catch in the Java language is provided to facilitate user capture exception and perform an exception. But if you use improper use, it will also affect the performance of the Java program. Therefore, pay attention to the following two points.
(1) Avoid using TRY / CATCH logic to applications
If you can use if, while, etc., you can handle it, then don't use TRY / CATCH statement as much as possible.
(2) Reusing exception
When the processing must be processed, it is necessary to reuse the existing exception objects as much as possible. Those in the abnormal process, generating an abnormal object to consume most of the time.
3. Threading
A thread is generally used in a high-performance application. Because threads make full use of the resources of the system. In other threads, the program can continue to process and run because of the other threads waiting for the hard disk or network read and write. However, it is used to use improper use and will affect the performance of the program.
Example 2: Use the Vector Class Correctly
Vector is primarily used to save various types of objects (including the same type and different types of objects). However, in some cases, use the performance of the program to bring performance. This is mainly determined by the two features of the VECTOR class. First, Vector provides thread safety protection features. Even many methods in the Vector class synchronize. But if you have confirmed that your application is a single thread, the synchronization of these methods is completely unnecessary. Second, when you look for various objects stored, it often spends a lot of time to match the type. These matches are completely unnecessary when these objects are in the same type. Therefore, it is necessary to design a single-threaded, saving a class or collection of a particular type object to replace the Vector class. The program used to replace is as follows (StringVector.java):
Public Class StringVector
{
PRIVATE STRING [] DATA;
PRIVATE INT COUNT;
Public stringvector () {this (10); // default size is 10}
Public StringVector (int initialsize)
{
Data = new string [initialsize];
}
Public Void Add (String STR)
{
// ignore null strings
IF (str == null) {return;}
EnsureCapacity (count 1);
Data [count ] = STR;
}
Private Void EnSurecapacity (int MINCAPACITY)
{
INT Oldcapacity = data.length;
IF (MINCAPACITY> Oldcapacity)
{
String olddata [] = data;
INT newcapacity = Oldcapacity * 2; data = new string [newcapacity];
System.ArrayCopy (OldData, 0, Data, 0, Count);
}
}
Public Void Remove (String Str)
{
IF (str == null) {return // ignore null str}
For (int i = 0; i { // Check for a match IF (Data [i] .Equals (str)) { System.ArrayCopy (Data, i 1, Data, I, Count-1); // Copy Data // Allow Previously Valid Array Element Be gc'd Data [- count] = NULL; Return; } } } Public final string getStringat (int index) { IF (INDEX <0) {Return Null;} Else if (INDEX> count) { Return null; // index is> # strings } Else {Return Data [INDEX]; // Index is good} } / * * * * * * * * * * * * * * Stringvector.java * * * * * * * * * * * * * * * * / So, code: Vector strings = new vector (); Strings.Add ("one"); Strings.Add ("Two"); String second = (string) strings.ementat (1); Can be replaced with the following code: StringVector strings = new stringvector (); Strings.Add ("one"); Strings.Add ("Two"); String second = strings.getstringat (1); This can improve the performance of the Java program by optimizing the thread. The procedures for test are as follows: TestCollection.java: Import java.util.vector; Public Class TestCollection { Public static void main (string args []) { TestCollection Collect = New TestCollection (); IF (args.length == 0) { System.out.println ( "USAGE: JAVA TESTCOLLECTION [Vector | StringVector]"); System.exit (1); } IF (args [0] .equals ("vector")) { Vector store = new vector (); Long Start = system.currenttimemillis (); For (int i = 0; i <1000000; i ) { Store.AddeElement ("string"); } Long finish = system.currenttimemillis (); System.out.println (FINISH-START); Start = system.currenttimemillis (); for (int i = 0; i <1000000; i ) { String result = (string) Store.Elementat (i); } FINISH = system.currenttimemillis (); System.out.println (FINISH-START); } Else IF (Args [0]. Equals ("stringvector"))) { StringVector store = new stringvector (); Long Start = system.currenttimemillis (); For (int i = 0; i <1000000; i ) {store.add ("string");} Long finish = system.currenttimemillis (); System.out.println (FINISH-START); Start = system.currenttimemillis (); For (int i = 0; i <1000000; i ) { String result = store.getstringat (i); } FINISH = system.currenttimemillis (); System.out.println (FINISH-START); } } } / * * * * * * * * * * * * * * Testcollection.java * * * * * * * * * * * * * * * * / The results of the test are as follows (assuming the standard time is 1, the smaller performance, the better): For the operation of thread, pay attention to the following aspects. (1) Prevent excessive synchronization As shown above, unnecessary synchronization often causes a decline in program performance. Therefore, if the program is a single thread, you must not use synchronization. (2) Synchronous method instead of synchronizing the entire code segment Synchronizing a method or function is better than synchronizing the entire code segment. (3) Increase the mechanism for each object using multiple "lock". Generally, each object has only one "lock", which indicates that "dead lock" occurs if two threads perform two different synchronization methods of an object. Even if these two methods do not share any resources. To avoid this problem, you can implement "multi-lock" mechanisms to an object. As follows: Class foo { Private static int var1; Private static object lock1 = new Object (); Private static int var2; Private static object lock2 = new object (); Public static void increment1 () { Synchronized (LOCK1) { Var1 ; } } Public static void increment2 () { SYNCHRONIZED (LOCK2) { VAR2 ; } } } 4. Input and output (I / O) Input and outputs include many aspects, but involving the most is the read and write operations for hard drives, networks, or databases. For read and write operations, it is divided into cache and no cache; for the operation of the database, there can be multiple types of JDBC drivers to choose. But no matter what, it will affect the performance of the program. Therefore, pay attention to the following: (1) Use the input and output buffer Use more caches as much as possible. However, if you want to refresh the cache, it is recommended not to use a cache. (2) Output stream and Unicode string When using Output Stream and Unicode strings, the WRITE class has a big overhead. Because it is to implement Unicode to byte (byte) conversion. Therefore, if possible, transition is implemented before using the Write class, or use the OutputStream class instead of the Writer class. (3) Use Transient when serialization When serialization of a class or object, it is to recognize the TRANSIENT type for those atomic or reconstructed grades. This will not be serialized each time. If these serialized objects are transmitted over the network, this small change has great improvement in performance. (4) Using Cache (cache) For objects or data that are often used and unclear, it can be stored in the cache. This will increase the speed of access. This is especially important for the result set returned from the database. (5) Using a fast JDBC drive (Driver) Java provides four ways to access the database. There are two kinds of JDBC drivers. One is a local drive out of Java; the other is a complete Java drive. Which of the specific use of the Java deployment itself is determined. 5. Some other experiences and techniques (1) Use local variables (2) Avoid setting or calling the variables in the same class during the same class (GET or SET). (3) Avoid generating the same variable in the loop or call the same function (the parameter variable is also the same) (4) Use Static, Final, Private and other keywords as possible (5) When copying a large amount of data, use the system.araycopy () command.