String efficient programming 2, 3 things (Java)

Source: Internet
Author: User

1, substring intercepts a "memory leak" that could be caused by a super-large string

Optimization and limitation of 2,+ operators

3,stringbuilder and StringBuffer

Comparison of simple character segmentation efficiency between 4,split and StringTokenizer

1, substring intercepts a "memory leak" that could be caused by a super-large string

We know that a char array is stored inside a string object. However, the char array may not be as long as the character set represented by string, but it might be a "superset". The string has a private constructor:

// Package Private constructor which shares value, array for speed.    String (intintchar  value[]) {        this. Value = value;          this. offset = offset;         this. Count = count;    }

This constructor allows you to use only part of the value[] as a string character set, and it does not intercept part of value[] to create a new char array, but instead saves it entirely.

Next, consider the implementation of the SUBSTRING function:

 PublicString substring (intBeginindex,intEndIndex) {        if(Beginindex < 0) {            Throw Newstringindexoutofboundsexception (Beginindex); }        if(EndIndex >count) {            Throw Newstringindexoutofboundsexception (EndIndex); }        if(Beginindex >EndIndex) {            Throw NewStringindexoutofboundsexception (EndIndex-beginindex); }        return(Beginindex = = 0) && (endIndex = = count))? This :            NewString (offset + beginindex, EndIndex-beginindex, value); }

SUBSTRING is using the constructor we mentioned above to construct the returned string, and Java does so with both advantages and disadvantages:

1) If we want to intercept many small strings from a large string, then these small strings share a large char[]. So, this is very efficient and avoids the time-space overhead of reallocating memory.

2) However, if we only intercept one or a few very small strings, the original string will be discarded, and these small strings are stored for a long time, so that we create a memory leak in a sense-we think the memory of the original string is released by the GC, but it does not, its main part- The huge char array is still referenced by his sub-string, although only a small part of it is used by them.

For this leak, the workaround is simple, using the following syntax

New String (str1.substring (5,100));

The constructor string (string) creates a new char[] for the new String. But the premise is that we are aware of the problems that substring can cause.

Optimization and limitation of 2,+ operators

We know that for the following syntax:

STR1 += "abc" = STR1 + "abc";

Java creates a new string object and an array of strings, stitching the original string and the "ABC" copy into a new array of strings. It is naturally very inefficient to repeat the addition of such strings, which, as best practice, should use StringBuilder.

In fact, Java has been optimized for + operations. Look at the following code:

String temp = "ABC" + + + ' D ';

The compiler has compiled the code optimizations into:

New StringBuilder (). Append ("ABC"). Append (+). Append (' D '). toString ();

Note

Also, if the code is simple, multiple strings are added:

String temp = "Hello" + "" + "world";

The compiler directly optimizes the

String temp = "Hello world";

)

Therefore, the continuous accumulation of efficiency is not worse than the use of StringBuilder, because it is originally a StringBuilder object continuous append to achieve.

However, if it is:

 for (int i=0; i<100; i++) {    temp+ = "abc";}

The compiler has no way of optimizing the ' + ' operation of multiple iterations within the for loop to use a continuous append operation with only one StringBuilder object. Therefore, it is still very inefficient.

In short, if all string concatenation can be done in one line with ' + ', then there is no efficiency problem; otherwise, it is better to use StringBuilder.

3,stringbuilder and StringBuffer

StringBuilder and StringBuffer usage are basically no different, but StringBuilder is not thread-safe, StringBuffer is thread-safe. StringBuffer locks on all public methods used for character manipulation-the synchronized keyword is used.

Let's test the efficiency of the single-threaded StringBuilder and StringBuffer, the following code:

 Public Static voidMain (string[] args) {LongT1 =System.nanotime (); StringBuffer StringBuffer=NewStringBuffer ();  for(inti=0; i<1000000; i++) {stringbuffer.append (A);        } stringbuffer.tostring (); Longt2 =System.nanotime (); System.out.println ("StringBuffer:" + (t2-t1)); T1=System.nanotime (); StringBuilder StringBuilder=NewStringBuilder ();  for(inti=0; i<1000000; i++) {stringbuilder.append (A);         } stringbuilder.tostring (); T2=System.nanotime (); System.out.println ("StringBuilder:" + (t2-t1)); }

Results:

stringbuffer:33979818StringBuilder:14061978

In single-threaded cases, the StringBuilder is more than a few times faster.

How is the multithreading situation stringbuffer efficiency? The following code tests:

Long T1 = System.nanotime ();Final StringBuffer stringbuffer = new StringBuffer ();Executorservice Executor= Executors.newfixedthreadpool (3);Countdownlatch Countdownlatch = new Countdownlatch (3);for (int i= 0;i < 3; i++) {Executor.execute (New Runnable () {@Override public void run () { for (int i= 0;i < 333333; i++) {Stringbuffer.append ("a");                    }                }            });Countdownlatch.countdown ();} stringbuffer.tostring ();Countdownlatch.await ();Long T2= System.nanotime ();System.out.println ("StringBuffer:" + (T2-T1));

Results:

stringbuffer:2603076

Although we use 3 worker threads, the efficiency is almost nothing higher than a single thread, which is the result of using locking in multithreading--the coordination of locks in multiple threads, which leads to frequent switching of threads and greatly reduces efficiency.

Although I really do not know what scenes need to use multi-threaded string assembly. Assuming that there is a very stringent performance requirement, I think you might consider using some non-locking multithreaded programming framework, such as disruptor--a lock-free ringbuffer framework that uses multiple producer threads to deliver a string object to the ring buffer. Assembled in the consumer with StringBuilder. (Asynchronous log processing similar to log4j 2)

4,split and StringTokenizer Compare the efficiency of simple character segmentation.

Many articles say that split is much more efficient than StringTokenizer and is beginning to think, but finds that there are serious problems with their test code. I did the test myself.

StringBuilder StringBuilder =NewStringBuilder ();  for(inti = 0; i < 1000000; i++) {stringbuilder.append (i); Stringbuilder.append (","); } String str=stringbuilder.tostring (); LongT1 =System.nanotime (); String[] Strarray= Str.split (","); Longt2 =System.nanotime (); System.out.println ("Split:" + (T2-t1)); String str1=stringbuilder.tostring (); T1=System.nanotime (); StringTokenizer StringTokenizer=NewStringTokenizer (str1, ",");  //list<string> strlist = new arraylist<string> (1000000);//or string[] StrArray1 = new String[stringtokenizer.counttokens ()];          for(inti = 0; i < 1000000; i++) {String subStr=Stringtokenizer.nexttoken ();  //Strlist.add (SUBSTR);//or Strarray1[i] =substr; } T2=System.nanotime (); System.out.println ("Token:" + (T2-T1));

Results:

split:248539389token:53191452

StringTokenizer is 4 times times faster than split.

But the comparison above is not fair in some cases, split returns an array, and StringTokenizer's next method can only browse tokens individually. What happens if StringTokenizer is asked to save the returned substring in the list? Open the commented-out code in the above code snippet so that StringTokenizer also saves the tokens in the list or array, and then tests it.

Results:

split:254496592token:303926083

In this case, the efficiency of StringTokenizer is worse. Therefore, can not generalize split or stringtokenizer who efficiency high, but also to see if used. If you need to put the results in an array or list, split is simpler and more efficient. (see 2 kinds of algorithm efficiency and no essential difference, the difference in the use of array or list, specifically from the JDK source code to analyze)

String efficient programming 2, 3 things (Java)

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.