29 Essentials to help you get better with Java code optimization

Source: Internet
Author: User
Tags int size try catch

In Java programs, most of the reasons for performance problems lie not in the Java language, but in the program itself. It is important to develop good coding habits, such as using the Java.lang.String class and the Java.util.Vector class correctly and skillfully, which can significantly improve the performance of the program. Let's take a concrete look at the problem in this area.

29 Essentials to help you get better with Java code optimization

1. It is not possible to derive a class that specifies the final modifier of the class with the final modifier.

In the Java Core API, there are many examples of final applications, such as java.lang.String. Specifying final for the string class prevents people from overwriting the length () method. In addition, if you specify a class to be final, all methods of that class are final. The Java compiler looks for the opportunity Inline (inline) for all final methods (this is related to the specific compiler implementation). This will increase the performance by an average of 50%.

advertisement

2, try to reuse objects.

In particular, when string objects are used, StringBuffer is used instead when strings are concatenated. Because the system not only takes time to generate objects, it may take time for them to be garbage collected and processed later. Therefore, generating too many objects will have a significant impact on the performance of the program.

3. Use local variables as much as possible, parameters passed when invoking a method, and temporary variables created in the call are saved in the stack, faster.

Other variables, such as static variables, instance variables, and so on, are created in the heap and are slower. Also, depending on the compiler/JVM, local variables may be further optimized. See Use stack variables whenever possible.

4, do not repeat the initialization of variables

By default, when invoking the constructor of a class, Java initializes the variable to a deterministic value: All objects are set to NULL, integer variables (byte, short, int, long) are set to 0,float and double variables are set to 0.0, and the logical value is set to False. This is especially important when a class is derived from another class, because all constructors in the constructor chain are called automatically when an object is created with the new keyword.

advertisement

5 . In Java + Oracle's application development,SQL statements embedded in Java should use uppercase as much as possible to alleviate the parsing burden of the Oracle parser.

6, in the Java programming process, the database connection, I/O flow operation must be careful, after use, even if closed to release resources.

Because the operation of these large objects can cause large overhead, a slight carelessness, which can lead to serious consequences.

7, because the JVM has its own GC mechanism, does not require too much consideration of program developers, to a certain extent, to alleviate the burden of developers, but also missed the hidden dangers, excessive creation of objects will consume the system of large amounts of memory, serious will lead to memory leaks, it is important to ensure the timely recovery of outdated objects .

The JVM recycles garbage by saying that the object is not being referenced; however, the JVM's GC is not very witty, and even if the object satisfies the garbage collection condition, it does not necessarily get reclaimed immediately. Therefore, we recommend that you manually set NULL when the object is used.

8, when using the synchronization mechanism, should try to use method synchronization instead of code block synchronization.

9, minimize the repetition of the variable calculation

advertisement

For example: for (int i = 0;i < list.size; i + +) {

...

}

Should be replaced by:

for (int i = 0,int len = list.size (); i < Len; i + +) {

...

}

10, try to use the lazy loading strategy, that is, when needed to start the creation.

For example: String str = "AAA";

if (i = = 1) {

List.add (str);

}

Should be replaced by:

if (i = = 1) {

String str = "AAA";

List.add (str);

}

11, cautious use of abnormal

Exceptions are bad for performance. Throwing an exception begins with creating a new object. The constructor of the Throwable interface calls the local (Native) method named Fillinstacktrace (), the Fillinstacktrace () method examines the stack, and collects the call trace information. Whenever an exception is thrown, the VM must adjust the call stack because a new object is created during processing. Exceptions can only be used for error handling and should not be used for control procedures.

advertisement

12, do not use in the loop:

Try {

} catch () {

}

It should be placed at the outermost layer.

13, the use of StringBuffer:

StringBuffer represents a mutable, writable string.

There are three methods of construction:

StringBuffer (); 16-character space is assigned by default

StringBuffer (int size); Allocate a space of size characters

StringBuffer (String str); Allocate 16 characters +str.length () character space

You can use the StringBuffer constructor to set its initialization capacity, which can significantly improve performance.

The constructor mentioned here is stringbuffer (int length), and the length parameter represents the number of characters that the current stringbuffer can hold. You can also use the ensurecapacity (int minimumcapacity) method to set its capacity after the StringBuffer object is created. First we look at the default behavior of StringBuffer and then find a better way to improve performance.

StringBuffer maintains a character array internally, and when you use the default constructor to create a StringBuffer object, because the initialization character length is not set, the capacity of StringBuffer is initialized to 16 characters. This means that the default capacity is 16 characters. When the stringbuffer reaches its maximum capacity, it will increase its capacity to twice times that of the current 2, i.e. (+2 of the old value). If you use the default value, and then append the character to it after initialization, it will increase the capacity to 34 (2*16+2) when you append to the 16th character and increase the capacity to 70 (2*34+2) when you append to 34 characters. Whenever StringBuffer reaches its maximum capacity, it will have to create a new character array and then re-copy both old and new characters-which is a bit too expensive. So it is always wrong to set a reasonable initialization capacity value for StringBuffer, which results in an immediate performance gain. The effect of the adjustment of the StringBuffer initialization process is evident. Therefore, using an appropriate capacity value to initialize the StringBuffer is always the best advice.

14, reasonable use of Java class Java.util.Vector.

To put it simply, a vector is an array of java.lang.Object instances. A vector is similar to an array, and its elements can be accessed by an integer index. However, after the object of the vector type is created, the size of the object can be expanded and scaled down depending on the element's addition or deletion. Consider the following example of adding elements to a vector:

Object BJ = new Object ();

Vector v = new vector (100000);

for (int i=0;

i<100000; i++) {v.add (0,obj);}

The code above is detrimental to performance unless there is absolutely sufficient reason to require that new elements be inserted in front of the vector each time. In the default constructor, the initial storage capacity of the vector is 10 elements, and if the new element is added with insufficient storage capacity, then the storage capacity is doubled at a later time. The vector class, like the object StringBuffer class, replicates all existing elements to the new storage space each time the storage capacity is extended. The following code fragment is a few orders of magnitude faster than the previous example:

Object BJ = new Object ();

Vector v = new vector (100000);

for (int i=0; i<100000; i++) {v.add (obj);}

The same rule applies to the Remove () method of the vector class. Because there is no "gap" between the elements in the vector, removing any other element except the last element causes the element to move forward after the element is deleted. That is, removing the last element from the vector is several times lower than deleting the first element "overhead".

Suppose you want to remove all the elements from the previous vector, we can use this code:

for (int i=0; i<100000; i++)

{

V.remove (0);

}

However, the preceding code is a few orders of magnitude slower than the following code:

for (int i=0; i<100000; i++)

{

V.remove (V.size ()-1);

}

The best way to remove all elements from object V of vector type is:

V.removeallelements ();

Assume that the vector type of object V contains the string "Hello". Consider the following code, which removes the "Hello" string from the vector:

String s = "Hello";

int i = V.indexof (s);

if (I! =-1) v.remove (s);

The code looks like nothing wrong, but it's also bad for performance. In this code, the IndexOf () method searches for the string "Hello" in the Order of V, and the Remove (s) method also searches in the same order. The revised version is:

String s = "Hello";

int i = V.indexof (s);

if (i! =-1) v.remove (i);

In this version, we can avoid a second search by giving the exact index position of the element to be deleted directly in the Remove () method. A better version is:

String s = "Hello"; V.remove (s);

Finally, let's look at a snippet of the vector class:

for (int i=0; I++;i < V.length)

If v contains 100,000 elements, this code fragment will call the V.size () method 100,000 times. Although the size method is a simple method, it still requires the overhead of a method call, at least the JVM needs to configure it and clear the stack environment. Here, the code inside the for loop does not modify the size of the vector type Object V in any way, so the code above is best rewritten in this form:

int size = V.size (); for (int i=0; I++;i<size)

While this is a simple change, it still wins performance. After all, every CPU cycle is valuable.

...

15. When copying large amounts of data, use the system.arraycopy () command.

16, code refactoring: Enhance the readability of the code .

For example:

public class Shopcart {

Private List carts;

...

public void Add (Object item) {

if (carts = = null) {

Carts = new ArrayList ();

}

Crts.add (item);

}

public void Remove (Object item) {

if (carts. Contains (item)) {

Carts.remove (item);

}

}

Public List Getcarts () {

Returns a read-only list

return collections.unmodifiablelist (carts);

}

Not recommended this way

This.getcarts (). Add (item);

}

17. Create an instance of the class without the new keyword

When you create an instance of a class with 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 the design pattern, creating a new object instance using the Clone () method is straightforward if you create the object in Factory mode. For example, here is a typical implementation of the factory pattern:

public static Credit Getnewcredit () {

return new credit ();

}

The improved code uses the Clone () method, as follows:

private static Credit Basecredit = new Credits ();

public static Credit Getnewcredit () {

return (Credit) Basecredit.clone ();

}

The idea above is also useful for array processing.

18. Multiplication and division

Consider the following code:

for (val = 0; Val < 100000; Val +=5) {

Alterx = val * 8; Myresult = val * 2;

}

Replacing multiplication operations with shift operations can greatly improve performance. The following is the modified code:

for (val = 0; Val < 100000; val + = 5) {

Alterx = Val << 3; Myresult = Val << 1;

}

The modified code does not multiply by 8, but instead shifts to the equivalent left-shifted 3-bit operation, with each left shift of 1 bits equal to 2 times. Accordingly, the right-shift 1-bit operation is equivalent to dividing by 2. It is worth mentioning that although the shift operation is fast, but may make the code more difficult to understand, so it is best to add some comments.

19. Close the useless session in the JSP page.

A common misconception is that the session is created when there is client access, but the fact is that it is not created until a statement such as Httpservletrequest.getsession (true) is called by a server-side program, and note that if the JSP does not display the use <> Close session, the JSP file is automatically translated into a servlet with such a statement httpsession session = Httpservletrequest.getsession (true); This is also the origin of the hidden session object in JSP. Because the session consumes memory resources, if you do not intend to use the session, you should close it in all JSPs.

For those pages that do not need to track session state, turning off automatically created sessions can save some resources. Use the following Page directive: <%@ page session= "false"%>

20. JDBC and I/O

If your application needs to access a large data set, you should consider using block extraction. By default, JDBC extracts 32 rows of data at a time. For example, if we were to traverse a 5000-row recordset, JDBC had to call the database 157 times to fetch all the data. If you change the block size to 512, the number of times the database is called will be reduced to 10 times.

21. servlet and Memory usage

Many developers randomly save a lot of information to a user session. At some point, objects saved in the session are not reclaimed in a timely manner by the garbage collection mechanism. From a performance perspective, the typical symptom is that the user feels that the system is periodically slowing down, but cannot attribute the cause to any specific component. If you monitor the JVM's heap space, it behaves as if the memory usage is abnormally steep and steep.

There are two main ways to solve this type of memory problem. The first approach is to implement the Httpsessionbindinglistener interface in all beans scoped to the session. This allows the resources used by the bean to be explicitly freed as long as the Valueunbound () method is implemented.

Another option is to invalidate the session as quickly as possible. Most application servers have the option to set the session deprecation interval. Alternatively, you can programmatically invoke the session's Setmaxinactiveinterval () method, which is used to set the maximum interval of time, in seconds, that the servlet container allows for client requests before the session is invalidated.

22. Use buffer mark

Some application servers have joined the JSP-oriented buffer tagging feature. For example, BEA's WebLogic server supports this feature from version 6.0, and the Open Symphony Project also supports this feature. The JSP buffer tag can buffer the page fragment as well as the entire page. When the JSP page executes, if the target fragment is already in the buffer, the code that generated the fragment is no longer executed. Page-level buffering captures requests for a specified URL and buffers the entire result page. This feature is extremely useful for shopping baskets, catalogs, and the homepage of the portal site. For such applications, page-level buffering can save the results of page execution for subsequent requests to use.

23, select the appropriate reference mechanism

In a typical JSP application system, the page header, footer section is often extracted, and then as needed to introduce the page header, footer. Currently, there are two main ways to introduce external resources into JSP pages: include directives, and include actions.

Include directives: For example, <%@ include file= "copyright.html"%>. The directive introduces the specified resource at compile time. Before compiling, the page with the include directive and the specified resource are merged into a single file. The referenced external resources are determined at compile time, and the resource is more efficient than the runtime.

Include action: For example <jsp:include page= "copyright.jsp"/>. This action introduces the results generated after the specified page executes. Because it completes at run time, the control of the output results is more flexible. However, using the include action is only advantageous when the referenced content changes frequently, or if the referenced page cannot be determined until a request to the main page is not present.

24. Timely removal of sessions that are no longer needed

In order to clear a session that is no longer active, many application servers have a default session timeout, which typically takes 30 minutes. When the application server needs to save more sessions, if the memory capacity is insufficient, the operating system will transfer some of the memory data to disk, and the application server may dump some inactive sessions to disk based on the most recently used (most recently used) algorithm, and may even throw "out of memory" Abnormal. In large-scale systems, the cost of serialization sessions is expensive. When the session is no longer needed, the Httpsession.invalidate () method should be called in time to clear the session. The Httpsession.invalidate () method can usually be called on an app's exit page.

25. Do not declare the array as: public static final.

26. Discussion on the traversal efficiency of HashMap

The traversal of key and value pairs in HashMap is often encountered, as in the following two ways: map<string, string[]> paramap = new

?

Hashmap<string, string[]> ();

....//The first cycle of the.//

set<string> appfielddefids = Paramap.keyset ();

for (String appfielddefid:appfielddefids) {

String[] values = Paramap.get (APPFIELDDEFID);

......

}

A second loop

For (entry<string, string[]> entry:paraMap.entrySet ()) {

String Appfielddefid = Entry.getkey ();

String[] values = Entry.getvalue ();

.......

}

The first implementation is significantly less efficient than the second.

The analysis is as follows set<string> Appfielddefids = Paramap.keyset (); is to get keyset from HashMap first.

The code is as follows:

?

Public set<k> KeySet () {

set<k> KS = KeySet;

return (KS! = null? KS: (KeySet = new KeySet ()));

}

Private class KeySet extends Abstractset<k> {

Public iterator<k> Iterator () {

return Newkeyiterator ();

}

public int size () {

return size;

}

Public Boolean contains (Object o) {

return ContainsKey (o);

}

public boolean remove (Object o) {

return HashMap.this.removeEntryForKey (o)! = null;

}

public void Clear () {

HashMap.this.clear ();

}

}

In fact, it is to return a private class keyset, which is inherited from Abstractset and implements the set interface.

And look at the syntax of the for/in loop.

for (declaration:expression)

Statement

In the implementation phase is translated into the following various

for (iterator<e> #i = (expression). Iterator (); #i. Hashnext ();) {

Declaration = #i. Next ();

Statement

}

Therefore, Hashmap.keyset () is called in the first for statement for (String appfielddefid:appfielddefids). Iterator ()

And this method calls the Newkeyiterator ()

Iterator<k> Newkeyiterator () {

return new Keyiterator ();

}

Private class Keyiterator extends Hashiterator<k> {

Public K Next () {

Return NextEntry (). GetKey ();

}

}

So, in for, you still call the

The iterator used in the second loop for (entry<string, string[]> Entry:paraMap.entrySet ()) is one of the following internal

Class

Private class Entryiterator extends Hashiterator<map.entry<k,v>> {

Public map.entry<k,v> Next () {

return NextEntry ();

}

}

At this time the first loop to get the key, the second loop to get HashMap entry efficiency is the second loop reflected from the loop you can directly take the key and value value and the first loop or have to reuse the HashMap get (Object key) To fetch value values now look at the get (Object key) method of HashMap

Public V get (Object key) {

Object k = masknull (key);

int hash = hash (k);

int i = indexfor (hash, table.length); Entry[] Table

entry<k,v> e = table;

while (true) {

if (E = = null)

return null;

if (E.hash = = Hash && eq (k, E.key))

return e.value;

e = E.next;

}

}

In fact, the hash value is used to take out the corresponding entry to make comparisons, so use the first loop equivalent to two times into the HashMap entry

While the second loop takes the value of entry, it is more efficient than the first loop by taking key and value directly. In fact, according to the concept of the map should also be a second loop better, it is a key and value pairs, it is not a good choice to separate the key and value operation here.

27. Use of array (arrays) and arrylist

Array ([]): The most efficient, but its capacity is fixed and can not be changed dynamically;

ArrayList: Capacity can be dynamically increased, but sacrificing efficiency;

Based on efficiency and type checking, use an array whenever possible and use arraylist! if you cannot determine the size of the array

ArrayList is a complex version of array

ArrayList internally encapsulates an array of type Object, which, in general terms, has no intrinsic difference, and even ArrayList many methods, such as index, INDEXOF, Contains, Sort is the corresponding method of calling array directly on the basis of an internal array.

ArrayList the type information is discarded when the object is stored, all objects are masked as object, and the type is not checked at compile time, but the runtime will give an error.

Note: Support for generics has been added to Jdk5, and type checking can already be done when using ArrayList.

From this point of view, the difference between the ArrayList and the array is mainly due to the efficiency of the dynamic volume increase

28. Use HashMap and ArrayList as much as possible , it is not recommended to use Hashtable and vectors unless necessary, which results in a performance overhead due to the use of synchronization mechanisms.

29. The difference between StringBuffer and StringBuilder:

Java.lang.StringBuffer A variable sequence of characters for thread safety. A string-like buffer, but cannot be modified.

StringBuilder. The Java.lang.StringBuilder class should usually be preferred over this class because it supports all the same operations, but it is faster because it does not perform synchronization. For better performance, you should specify its capacity whenever possible when constructing stirngbuffer or Stirngbuilder. Of course, if you're working with a string that's not more than 16 characters long, you don't have to. Using Stirngbuilder in the same situation can only achieve a performance gain of around 10%-15% compared to using stringbuffer, but it risks a multi-thread insecurity. In real-world modular programming, a programmer in charge of a module may not be able to clearly determine whether the module will be put into a multithreaded environment, so: unless you can determine that your system's bottleneck is on StringBuffer, and that your module will not run in multithreaded mode, StringBuffer it.

...

Other additions:

1. Remove objects that are no longer in use and set to NULL

2. Use final,static and other keywords as much as possible

3. Use buffered objects whenever possible

How to optimize code to make Java source files and compiled class files smaller

1 use inheritance as much as possible, the more methods you inherit, the less code you will write.

2 Open the Java compiler's tuning options: javac-o This option removes the line number from the class file and can

Some private, static,final, small-section method declarations are called by the inline method

3 Extract the common code

4 Do not initialize very large arrays, although initializing an array in Java code is just a line of code, but

The compiled code is a line of code that inserts an array of elements, so if you have a large amount of data that needs to exist in the array

, you can put the data in a string, and then parse the string into the array at run time

5th type of object will occupy a lot of space, if you want to store a large number of date objects, you can consider storing it as

Long, which is then converted to date type when used

6 class name, method name and variable name try to use a short name as much as possible, consider using Hashjava, Jobe, obfuscate and Jshrink tools to do the job automatically.

7 define static final type variables into interface

8 arithmetic operations can be shifted left/right, do not use * and/operations, the same operations do not operate multiple times

2. Do not initialize variables two times

Java initializes the variable by default to a known value by calling the unique class constructor. All objects are set to Null,integers (Byte, short, int, long) set to 0,float and double set to 0.0,boolean variable set to False. This is especially important for classes that extend from other classes, which are called automatically when you create an object with a new keyword.

3. Make the class final wherever possible

A class marked as final cannot be extended. There are a number of examples of this technology in the core Java API, such as java.lang.String. Marking the string class as final prevents developers from creating a length method of their own implementation.

In more depth, if the class is final, the methods of all classes are final. The Java compiler may inline all methods (this depends on the implementation of the compiler). In my test, I've seen an average increase of 50% in performance.

9. Exceptions are thrown where they need to be thrown, and try catch can be consolidated to integrate

?

try {

Some.method1 (); Difficult for Javac

} catch (Method1exception e) {//and the JVM runtime

Handle exception 1//To optimize this

}//code

try {

SOME.METHOD2 ();

} catch (Method2exception e) {

Handle Exception 2

}

try {

Some.method3 ();

} catch (Method3exception e) {

Handle Exception 3

}


? The code has been more easily optimized by the compiler

try {

Some.method1 (); Easier to optimize

SOME.METHOD2 ();

Some.method3 ();

} catch (Method1exception e) {

Handle Exception 1

} catch (Method2exception e) {

Handle Exception 2

} catch (Method3exception e) {

Handle Exception 3

}

Optimization of the For loop

Replace ...

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

...

}

With ...

for (int i = 0, n = collection.size (); i < n; i++) {

...

}

5. In Java + Oracle's application development, SQL statements embedded in Java should use uppercase as much as possible to alleviate the parsing burden of the Oracle parser.

10, try to use the lazy loading strategy, that is, when needed to start the creation.

For example: String str = "AAA";

if (i = = 1) {

List.add (str);

}

Should be replaced by:

if (i = = 1) {

String str = "AAA";

List.add (str);

}

12, do not use in the loop:

Try {

} catch () {

}

It should be placed at the outermost

The above is 29 points to help you better complete the Java code optimization of all the content, hoping to help everyone in Java development better to work.

29 Essentials to help you get better with Java code optimization

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.