Java language idioms
1. cycle
In important loops, eliminate method calls when determining loop termination.
For example: will
for(int i=0; i<collection.size();i++){ ... }
Replace with…
for(int i=0; n=collection.size();i<n;i++){...}
Usually, move items that are not related to the loop index outside the loop.
for(int i=0; terminal=x.length;i<terminal;i++){x[i] = x[i]/scaleA *scaleB;}
It should be:
Double scale = scaleB*scaleA;for(int i=0; terminal=x.length;i<terminal;i++){x[i] = x[i]/scale;}
2. string
Eliminate string concatenation
When creating long strings, always use StringBuffter instead of String
Pre-allocate StringBuffer space StringBuffer sb = new StringBuffer(5000);
3. Basic data types
Use basic data types in important loops (int data is usually faster than long/double data)
Wrapping classes of basic data types (Boolean, Integer, etc.) are mainly used when the passed method parameter must be a reference to an object (rather than a basic data type)
Use the static final modifier on all constant algebraic expressions to make constants easier to reference (the compiler precomputes constant expressions)
4. abnormal
Exceptions are only used for a single true error condition such that throwing an exception and executing a catch block are expensive (mainly due to obtaining a snapshot of the thread stack when creating an exception)
An exception is thrown only when the condition is truly exceptional. To throw an exception, you first create a new object.
The constructor of the Throwable interface calls the native method named fillInStackTrace(). The fillInStackTrace() method checks the stack and collects call tracing information.
Whenever an exception is thrown, the VM has to adjust the call stack because a new object is created during processing.
Exceptions should only be used for error handling and should not be used to control program flow.
Make compiler and runtime optimizations by placing several method calls in a try/catch block instead of implementing several try/catch blocks for each method call
try{ Some.method1(); //Difficut for java1.4 }catch(method1Exception e){ handle exception
1 // to optimize this code } try{ Some.method2(); //Difficut for java1.4 }catch(method2Exception e){ handle exception
2 // to optimize this code } try{ Some.method3(); //Difficut for java1.4 }catch(method3Exception e){ handle exception
3 // to optimize this code
}
should be written as:
try{ Some.method1(); Some.method2(); Some.method3(); //Difficut for java1.4 }catch(method1Exception e){ handle exception 1 }catch(method2Exception e){ handle exception 2 }catch( method3Exception e){ handle exception 3 }
5. benchmark
Note that all of these tips will vary between platforms and virtual machines
For example: in some servlet containers, it is faster to output bytes through an OutputStream
2. In other containers, it will be faster to output characters through a PrintWriter
These tips describe the most portable recommendations
You may need to run some benchmarks to determine what is fastest on your platform
6. Create an instance of a class without using the new keyword
When you create an instance of a class using the new keyword, all constructors in the constructor chain are automatically called.
But if an object implements the Cloneable interface, we can call its clone() method. The clone() method does not call any class constructors.
When using Design Pattern, if you use Factory mode to create an object, it is very simple to use the clone() method to create a new object instance.
For example, the following is a typical implementation of the Factory pattern:
public static Credit getNewCredit() { return new Credit(); }
After optimization:
private static Credit BaseCredit = new Credit(); public static Credit getNewCredit() { return (Credit) BaseCredit.clone();}
The above ideas are also useful for array processing.
7. Use non-blocking I/O
JDKs with lower Java versions do not support non-blocking I/O APIs. To avoid I/O blocking, some applications create a large number of threads (in better cases, a buffer pool is used). This technique can be seen in many applications that must support concurrent I/O streams, such as Web servers, quotation and auction applications, etc. However, creating Java threads requires considerable overhead.
JDK 1.4 introduced a non-blocking I/O library (java.nio). If your application requires an older version of the JDK, there is a package that supports non-blocking I/O.
8. Do not initialize variables repeatedly
By default, when calling the constructor of a class, Java will initialize variables to certain values: all objects are set to null, integer variables (byte, short, int, long) are set to 0, and float and double variables are set to 0.0, the logical value is set to false.
This should be especially noted when a class is derived from another class, because when an object is created using the new keyword, all constructors in the constructor chain will be automatically called.
9. Try to specify the final modifier of the class
Classes with the final modifier are not derived. In the Java core API, there are many examples of applying final, such as java.lang.String. Specifying final for the String class prevents people from overriding the length() method.
In addition, if a class is designated as final, all methods of the class will be final. The Java compiler will look for opportunities to inline all final methods (this depends on the specific compiler implementation). This can improve performance by an average of 50%.
10. Use local variables whenever possible
The parameters passed when calling the method and the temporary variables created during the call are saved in the stack (Stack), which is faster. Other variables, such as static variables, instance variables, etc., are created in the Heap and are slower. In addition, depending on the specific compiler/JVM, local variables may be further optimized. See Use Stack Variables Wherever Possible.
11. Multiplication and division
Consider the following code:
for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }
After optimization:
for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }
The modified code no longer performs the operation of multiplying by 8, but instead uses the equivalent operation of shifting 3 bits to the left. Each left shift of 1 bit is equivalent to multiplying by 2. Correspondingly, a right shift operation of 1 bit is equivalent to dividing by 2. It is worth mentioning that although the shift operation is fast, it may make the code more difficult to understand, so it is best to add some comments.
private static Credit BaseCredit = new Credit(); public static Credit getNewCredit() {return (Credit) BaseCredit.clone();}