在自己以往的学习及工作经验中,形成的概念:
String对象具有不变性,一旦String对象生成,就不可能在被改变;
StringBuffer 线程安全;
StringBuilder 线程不安全;
现针对以上三种Object,在自己机器上手写代码做测试,以验证三者的效率差异:
三种Object同时在3种不同的字符串拼接中,循环5w次,耗时对比:
Source Code: Test.java
public class Test {
static int len = 50000;
public static void main(String[] args) {
System.out.println("---testOne()---");
testOne();
System.out.println("---testTwo()---");
testTwo();
System.out.println("---testThree()---");
testThree();
}
static void testOne() {
Long t1 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
String result1 = "String" + "and" + "String" + "append";
}
Long t2 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
StringBuffer sb = new StringBuffer();
sb.append("String");
sb.append("and");
sb.append("String");
sb.append("append");
}
Long t3 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
StringBuilder sb = new StringBuilder();
sb.append("String");
sb.append("and");
sb.append("String");
sb.append("append");
}
Long t4 = System.currentTimeMillis();
System.out.println("String:" + (t2 - t1)+"ms");
System.out.println("StringBuffer:" + (t3 - t2)+"ms");
System.out.println("StringBuilder:" + (t4 - t3)+"ms");
}
static void testTwo() {
String temp = "abcd";
String temp2 = "abcd";
String temp3 = "abcd";
Long t1 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
String result1 = temp + temp2 + temp3;
}
Long t2 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
StringBuffer sb = new StringBuffer();
sb.append(temp);
sb.append(temp2);
sb.append(temp3);
}
Long t3 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
StringBuilder sb = new StringBuilder();
sb.append(temp);
sb.append(temp2);
sb.append(temp3);
}
Long t4 = System.currentTimeMillis();
System.out.println("String:" + (t2 - t1)+"ms");
System.out.println("StringBuffer:" + (t3 - t2)+"ms");
System.out.println("StringBuilder:" + (t4 - t3)+"ms");
}
static void testThree() {
String temp = "abcd";
String temp2 = "abcd";
String temp3 = "abcd";
Long t1 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
String result1 = "String" + "and" + "String" + "append" + temp
+ temp2 + temp3;
}
Long t2 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
StringBuffer sb = new StringBuffer();
sb.append("String");
sb.append("and");
sb.append("String");
sb.append("append");
sb.append(temp);
sb.append(temp2);
sb.append(temp3);
}
Long t3 = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
StringBuilder sb = new StringBuilder();
sb.append("String");
sb.append("and");
sb.append("String");
sb.append("append");
sb.append(temp);
sb.append(temp2);
sb.append(temp3);
}
Long t4 = System.currentTimeMillis();
System.out.println("String:" + (t2 - t1)+"ms");
System.out.println("StringBuffer:" + (t3 - t2)+"ms");
System.out.println("StringBuilder:" + (t4 - t3)+"ms");
}
}
反编译Test.class
import java.io.PrintStream;
public class Test
{
static int len = 50000;
public static void main(String[] args) {
System.out.println("---testOne()---");
testOne();
System.out.println("---testTwo()---");
testTwo();
System.out.println("---testThree()---");
testThree();
}
static void testOne()
{
Long t1 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
String str = "StringandStringappend";
}
Long t2 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
StringBuffer sb = new StringBuffer();
sb.append("String");
sb.append("and");
sb.append("String");
sb.append("append");
}
Long t3 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
StringBuilder sb = new StringBuilder();
sb.append("String");
sb.append("and");
sb.append("String");
sb.append("append");
}
Long t4 = Long.valueOf(System.currentTimeMillis());
System.out.println("String:" + (t2.longValue() - t1.longValue()) + "ms");
System.out.println("StringBuffer:" + (t3.longValue() - t2.longValue()) + "ms");
System.out.println("StringBuilder:" + (t4.longValue() - t3.longValue()) + "ms");
}
static void testTwo() {
String temp = "abcd";
String temp2 = "abcd";
String temp3 = "abcd";
Long t1 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
String str1 = temp + temp2 + temp3;
}
Long t2 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
StringBuffer sb = new StringBuffer();
sb.append(temp);
sb.append(temp2);
sb.append(temp3);
}
Long t3 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
StringBuilder sb = new StringBuilder();
sb.append(temp);
sb.append(temp2);
sb.append(temp3);
}
Long t4 = Long.valueOf(System.currentTimeMillis());
System.out.println("String:" + (t2.longValue() - t1.longValue()) + "ms");
System.out.println("StringBuffer:" + (t3.longValue() - t2.longValue()) + "ms");
System.out.println("StringBuilder:" + (t4.longValue() - t3.longValue()) + "ms");
}
static void testThree() {
String temp = "abcd";
String temp2 = "abcd";
String temp3 = "abcd";
Long t1 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
String str1 = "StringandStringappend" + temp +
temp2 + temp3;
}
Long t2 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
StringBuffer sb = new StringBuffer();
sb.append("String");
sb.append("and");
sb.append("String");
sb.append("append");
sb.append(temp);
sb.append(temp2);
sb.append(temp3);
}
Long t3 = Long.valueOf(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
StringBuilder sb = new StringBuilder();
sb.append("String");
sb.append("and");
sb.append("String");
sb.append("append");
sb.append(temp);
sb.append(temp2);
sb.append(temp3);
}
Long t4 = Long.valueOf(System.currentTimeMillis());
System.out.println("String:" + (t2.longValue() - t1.longValue()) + "ms");
System.out.println("StringBuffer:" + (t3.longValue() - t2.longValue()) + "ms");
System.out.println("StringBuilder:" + (t4.longValue() - t3.longValue()) + "ms");
}
}
测试运行结果:
将len设为50w,运行结果差异会更大;
总结:
对一个注重执行效率的系统,应该根据实际当中不同的业务需求,按需选用String, StringBuffer 或 StringBuilder。
----------------