Stringbuffer and vector Performance Optimization

Source: Internet
Author: User

 

Java makes development of complex applications relatively simple. There is no doubt that its ease of use is essential to Java's wide range of popularity. However, this ease of use is actually a double-edged sword. A well-designed Java program often has less performance than a well-designed C ++ program. In Java programs, most of the performance problems are not caused by the Java language, but by the program itself. It is very important to develop good coding habits. For example, to use Java. Lang. String and Java. util. Vector correctly and skillfully, it can significantly improve the program performance. Next we will analyze this problem in detail.

Java. Lang. String is one of the most frequently used and abused classes in Java. It is also one of the main causes of low code performance. Consider the following example:

String S1 =/"testing string /";
String S2 =/"concatenation performance /";
String S3 = S1 +/"/" + S2;

Almost all Java programmers know that the above Code is inefficient. So what should we do? You may try the following code:

Stringbuffer S = new stringbuffer ();
S. append (/"testing string /");
S. append (/"/");
S. append (/"concatenation performance /");
String S3 = S. tostring ();

Is this code more efficient than the first code snippet? The answer is no. The code here is actually the result after the compiler compiles the first code snippet. Since stringbuffer does not improve the code efficiency compared to using multiple independent string objects, so why are there so many Java books criticizing the first method and recommending 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 defaults the cache capacity of 16 characters. 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 calculates the total length after string appending. If the total length is greater than the storage capacity of stringbuffer, The append () method calls the private expandcapacity () method. The expandcapacity () method doubles the stringbuffer storage capacity each time it is called, and copies the existing character array content to the new bucket.

In the second code snippet (and in the compilation result of the first code snippet), because the final result of the string append operation is "testing String concatenation performance", it has 40 characters, the storage capacity of stringbuffer must be extended twice, resulting in two expensive replication operations. Therefore, at least one thing we can do better than the compiler is to allocate a stringbuffer with 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 why the previous code is less efficient than the following code:

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 create and remove a stringbuffer object and a string object. This is a waste, and we have avoided this situation in the second example.

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. A vector is similar to an array. Its elements can be accessed through an integer index. However, after a vector object is created, the object size can be expanded or reduced based on the addition or deletion of elements. 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 );}

Unless there are absolutely good reasons to require that the new elements be inserted before the vector each time, the above Code is not good for performance. In the default constructor, the initial storage capacity of the vector is 10 elements. If the storage capacity of the new element is insufficient when it is added, the storage capacity will be doubled each time. Like the stringbuffer class, the vector class copies all existing elements to the new storage space each time it expands the storage capacity. The following code snippets are several 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 each element in a vector cannot contain a "gap", deleting any element other than the last element causes the element to move forward after it is deleted. That is to say, deleting the last element from a vector is several times less overhead than deleting the first element.

We can use this code to delete all elements from the previous vector:

For (INT I = 0; I <100000; I ++) {v. Remove (0 );}

However, compared with the following code, the previous code is several orders of magnitude slower:

For (INT I = 0; I <100000; I ++) {v. Remove (V. Size ()-1 );}

The best way to delete all elements from Vector object V is:

V. removeallelements ();

Assume that the vector object V contains the string "hello ". Consider the following code. It will delete the "hello" string from this vector:

String S =/"Hello/"; int I = V. indexof (s); if (I! =-1) v. Remove (s );

These codes seem to have no errors, but they are also detrimental to performance. In this Code, the indexof () method searches for the string "hello" in sequence, and the remove (s) method also performs the same sequential search. The improved version is:

String S =/"Hello/"; int I = V. indexof (s); if (I! =-1) v. Remove (I );

In this version, the exact index position of the element to be deleted is directly given in the remove () method, thus avoiding the second search. A better version is:

String S =/"Hello/"; V. Remove (s );

Finally, let's look at a code snippet about the Vector class:

For (INT I = 0; I

If V contains 100,000 elements, the code snippet calls 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 JVM needs to configure and clear the stack environment for it. Here, the code inside the for loop does not modify the V Size of the vector object in any way, so the above Code should be rewritten to the following form:

Int size = V. Size (); For (INT I = 0; I

Although this is a simple change, it still wins the performance. After all, every CPU cycle is precious.

Poor code writing leads to reduced code performance. However, as shown in the example in this article, we only need to take some simple measures to significantly improve the Code performance.

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.