Most Web sites, and most Java books, say that using the StringBuffer class for string "Connect" operations is more efficient than a string class, so is that really the case? Here we actually test ourselves and see if both of them are highly efficient, The reason is then interpreted from the anti-compilation code.
In my blog: The difference between "abc" + "/" and "abc" + "/" in Java mentions that the class's String ' + ' operation is dependent on the StringBuilder class, while the JDK API documentation says that StringBuilder the class is StringBuffer faster than the class. So what is it? String Is the efficiency of the class high or the StringBuffer class efficient? Here we test it ourselves.
Broad framework of the program
Importjava.util.*; Public class stringtest{ Private Static Final intCOUNT =50000; Public Static void Main(string[] args) {Runtime run = runtime.getruntime ();LongStartTime, EndTime;LongStartmem, Endmem;//Recycle trashRUN.GC ();//Record the memory and time information at the beginning and print to the screenStartTime = System.currenttimemillis (); Startmem = Run.totalmemory ()-run.freememory (); System.out.println ("Time:"+ (NewDate ())); System.out.println ("Used Memory:"+ Startmem);//Execute code snippet that needs to be testedTest ();//Calculate the amount of memory and time spent, then print to the screenEndTime = System.currenttimemillis (); Endmem = Run.totalmemory ()-run.freememory (); System.out.println ("Time:"+ (NewDate ()) +", Spend time:"+ (endtime-starttime)); System.out.println ("Used Memory:"+ Endmem +", Added Memory:"+ (ENDMEM-STARTMEM)); } Public StaticStringTest(){//write a string connection operation or a stringbuffer "connect" Operation}}
System.currentTimeMillis();You can get the current time in milliseconds, so it's endTime-startTime roughly the test time that the method runs. Because the two acquisition time not only executes the test method but also acquires the system memory, and prints two messages.
run.totalMemory() - run.freeMemory()Can roughly get the memory currently used by the program, here we do not explain, there is not clear can refer to my other blog: "Get Java Program runtime memory information."
There is nothing more difficult to understand in this general framework, so just explain the two. Here's how we add the whole thing. test
Program code for the part under test
The code that needs to be tested is very simple:
StringClass Test Code
publicstatictest(){ ""; for(int i=0; i<COUNT; ++i){ str += i; } return str;}
StringBufferClass Test Code
publicstatictest(){ new StringBuffer(); for(int i=0; i<COUNT; ++i){ strbf.append(i); } return strbf.toString();}
I can't seem to let these two pieces of code display side-by ... Let's see.
This program is simple to connect from 0 to 49999, we create two classes, respectively, with these two pieces of code to start testing. OK, everything is ready, then the following is running the program, see the output?
Run results
The diagram on the left is the output of the test String class, and the right side is the StringBuffer result of the test:
| Test results for the String class |
Test results for the StringBuffer class |
Well, it's quite the opposite of guessing in the difference between "abc" + "/" and "abc" + "/" in Java, but you have to admit that StringBuffer classes are really String faster than classes. So, why? String Is the connection to a class not dependent on StringBuilder a class?
Explain this phenomenon from the source of anti-compilation
Because the code for the Anti-compilation will be long, here we only give the code of the String test Middle for loop part of the test class. If you are interested in the loop portion of the test StringBuffer class for , please check it yourself.
You can see the anti-compiled code in STRINGTEST.S by executing the following command:
Javap-c Stringtest.class > Stringtest.s
6:LDC #24//int 50000 8:If_icmpge One:New #8//class Java/lang/stringbuilder -:DUP the:invokespecial #9//Method java/lang/stringbuilder. " <init> ":() V -:Aload_0 +:invokevirtual #11//Method java/lang/stringbuilder.append: (ljava/lang/string;) Ljava/lang/stringbuilde R; A:iload_1 at:invokevirtual #25//Method Java/lang/stringbuilder.append: (I) Ljava/lang/stringbuilder; -:invokevirtual #15//Method java/lang/stringbuilder.tostring: () ljava/lang/string; in:Astore_0 -:iinc 1, 1 -:Goto 5
If you translate this code into Java code, this is the code below:
for(int i=0; i<COUNT; ++i){ new StringBuilder().append(str).append(i).toString();}
Note: The above program is exactly the same as the one we started with, even the code generated by the decompile is identical.
That is, each concatenated string produces a temporary StringBuilder object and discards the previous String object, so there is a significant overhead in memory. Because copying a string to a new array, constructing 2n objects and using too much memory leads to more frequent page faults, etc. String The class connection string is also StringBuffer many times worse than the class. So it's good to use or benefit from a larger string connection StringBuilder StringBuffer . Of course, in the case of string connection is less than the convenience of a String StringBuffer lot of, and there is no excessive performance problems, So you can use String classes completely.
It turns out that the String analogy is StringBuffer just wishful thinking. But also got some experience: there is something to be done to verify it, even if the result may be 108,000 of miles away from what we guessed, you never know/don't believe what the real answer is.
Written in 2015/05/17
which high efficiency string and StringBuffer in Java