http://blog.9cbs.net/chensheng913/archive/2004/09/06/96266.aspx
Java makes the development of complex applications relatively simple. There is no doubt that this ease of use is unable to play a wide range of java. However, this ease of use is actually a double-edged sword. A well-designed Java program, performance performance is often better than one design well-designed C program. In the Java program, most of the reason for performance issues are not in the Java language, but is the program itself. It is very important to develop a good code to write habits, such as correct, cleverly use Java.lang.String classes and Java.util.Vector classes, which can significantly improve program performance. Let's take a specific analysis of this problem.
In Java, the most frequent use is also the most abused class, may be Java.lang.String, which is also one of the most important reasons for code performance. Consider the following example:
String S1 = "Testing string"; string s2 = "contaTenation Performance"; string s3 = s1 "" S2;
Almost all Java programmers know that the above code is not high. So what should we do? Maybe you can try the following code:
StringBuffer s = new stringbuffer (); S.Append ("testing string"); S.Append ("" concatenation performance "); string s3 = s.toString ();
Is these code more efficient than the first code snippet? the answer is negative. The code here is actually the result of the compiler to compile the first code snippet. Since StringBuffer does not make the code improve the code with multiple independent String objects, why is there so many Java book criticize the first method, recommend the second method?
The second code snippet uses the StringBuffer class (the compiler will also use the StringBuffer class in the first segment), let's analyze the default constructor of the StringBuffer class, below is its code:
Public stringBuffer () {this (16);
The default constructor presets 16 characters of cache capacity. Now let's take a look at the Append () method of the StringBuffer class:
Public synchronized stringbuffer append (string str) {if (str == null) {str = string.valueof (STR);} int LEN = str.length (); int newcount = count len; if (Newcount> Value.LENGTH ) ExpandCapacity (newcount); str.getchars (0, len, value, count); count = newcount; return this;}
The Append () method first calculates the total length of the string to add completion. If this total length is greater than the storage capability of StringBuffer, the Append () method calls the private expandCapacity () method. The expandcapacity () method doubles StringBuffer storage capabilities while being called and copies the existing character array content to the new storage space.
In the second code snippet (and in the compiling result of the first code snippet), due to the final result of the string appended operation is "Testing String ConcateNation Performance", it has 40 characters, and the StringBuffer storage capacity must expand two Second, thereby led to the cost of expensive replication. Therefore, we can do at at least a better than the compiler, which is StringBuffer assigned an initial storage capacity greater than or equal to 40 characters, as shown below: StringBuffer s = new stringbuffer (45); S.Append ("Testing String "); S.Append (" "); S.Append (" ConcateNation Performance "); string s3 = s.toString ();
Consider the following example:
String s = ""; int sum = 0; for (int i = 1; i <10; i ) {SUM = I; s = s " " i;} s = s "=" sum ;
Analyze what the previous code is lower than the following code efficiency:
Stringbuffer SB = new stringbuffer (); int sum = 0; for (int i = 1; i <10; i ) {SUM = I; sb.append (i) .append (" ");} String s = Sb.append ("="). Append (sum) .tostring ();
The reason is that each S = S " " i operation must be created and removed a StringBuffer object and a String object. This is completely a waste, and in the second example we avoid this.
Let's take a look at another common Java class - Java.util.Vector. Simply put, a vector is an array of java.lang.object instances. The Vector is similar to the array, and its elements can be accessed through indexes in an integer. However, the object type object is created, and the size of the object can be expanded and reduced according to the increase or deletion of the element. Consider the example of adding an element to the vector:
Object obj = new object (); vector v = new vector (100000); for (int i = 0; i <100000; i ) {v.add (0, obj);}
Unless there is absolute reason, the new element is inserted into the vector every time, otherwise the above code is unfavorable. In the default constructor, the initial storage capability of the Vector is 10 elements. If the new element is not in the case of insufficient storage capacity, the storage capacity is doubled. All existing elements are copied to new storage spaces as the StringBuffer class. The following code snippet is 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 is also applicable to the Remove () method of the VECTOR class. Due to the "void" between the various elements in the vector, any other element other than the last element cannot be moved forward to the element after being deleted. That is, the last element is removed from the vector to "overhead" than the first element "overhead" is several times. Suppose you want to delete all elements from the previous Vector, we can use this code:
For (int i = 0; i <100000; i ) {v.remove (0);
However, compared with the code below, the previous code should be slower number quantity:
For (int i = 0; I <100000; i ) {v.remove (v.size () - 1);}
The best way to delete all elements from the Vector type object V is:
V.RemoveAllelements ();
Assuming that the VECTOR type object V contains a string "Hello". Consider the following code, it is to remove the "hello" string from this vector:
String s = "hello"; int i = v.indexof (s); if (i! = -1) v.Remove (s);
These codes have no mistakes, but it is also unfavorable to performance. In this code, the indexof () method sequentially searches for the V-search for strings "Hello", and the Remove (S) method is also available in the same order. The version after improvement is:
String s = "hello"; int i = v.indexof (s); if (i! = -1) v.remove (i);
In this version, we give the precise index position to delete elements directly in the Remove () method, thereby avoiding the second search. A better version is:
String s = "hello"; v.remove (s);
Finally, let's take a look at a code snippet about the VECTOR class:
For (int i = 0; i
If V contains 100,000 elements, this code snippet will call a v.size () method 100,000 times. Although the Size method is a simple method, it still needs a way to call overhead, at least JVM needs to configure 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 above code is best to be rewritten into the following form:
INT size = v.size (); for (int i = 0; i
Although this is a simple change, it still has won performance. After all, every CPU cycle is precious.
The poor code writing method causes the code performance to decline. However, as shown in this paper, we can significantly improve code performance as long as we take some simple measures.