Java code optimization notation (go to pick)

Source: Internet
Author: User
Tags error handling int size modifier

This article source address: 72841650

The resources available to the program (memory, CPU time, network bandwidth, etc.) are limited, and the purpose of optimization is to allow the program to complete the scheduled tasks with as few resources as possible. Optimization usually consists of two parts: reducing the volume of the Code and improving the efficiency of the Code. The main discussion in this paper is how to improve the efficiency of code.
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.

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%.

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 initialization 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, The 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.

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
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.

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 obj = 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 is like the StringBuffer class, where all existing elements are copied 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 obj = 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 <% @page session= "false"%> the session is closed, 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.
[P] [/p]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_r)
Statement

In the implementation phase is translated into the following various
for (iterator<e> #i = (expression_r). 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 an inner class as follows

Private class Entryiterator extends Hashiterator<map.entry<k,v>> {
Public map.entry<k,v> Next () {
return NextEntry ();
}
}

At this point the first loop gets the key, and the second loop gets HashMap's entry
Efficiency is the second loop that comes from the loop. You can take the key and value values directly.
The first loop still has to use HashMap's Get (Object key) to take the value

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 cycle equivalent to two times into the hashmap of the entry
And the second loop takes the value of entry directly after the key and value, the efficiency is higher than the first loop. 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, try to use HashMap and ArrayList, unless necessary, it is not recommended to use Hashtable and vectors, the latter due to the use of synchronization mechanism, resulting in performance overhead.

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.

Java code optimization notation (go to pick)

Related Article

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.