`

String, StringBuffer, StringBuilder 举例探究效率

阅读更多

在自己以往的学习及工作经验中,形成的概念:

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。

----------------

 

2
1
分享到:
评论

相关推荐

    String、StringBuilder和StringBuffer简单分析.md

    javase部分String的相关基础知识,String的构造方法总结比较以及各自的应用场景(代码举例),常用的容器类StringBuilder和StringBuffer的关系比较(图示)以及两者的区别联系和具体哪中场景下用哪个类。

    Java常用类与基础API-String的理解与不可变性

    利用 `StringBuilder` 或 `StringBuffer` 修改字符串: ```java String s = "abc"; StringBuilder sb = new StringBuilder(s); sb.setCharAt(0, 'd'); s = sb.toString(); ``` 这段代码首先使用 `StringBuilder` ...

    Java常用类String的面试题汇总(java面试题)

    8. String、StringBuilder和StringBuffer之间的区别? String是不可变的。每次对String做修改时,都会生成新的String对象。而StringBuilder和StringBuffer都是可变的字符串,意味着它们的内容可以被改变。...

    sonar常见问题及修改

    2. 使用 StringBuffer 而不是 StringBuilder:StringBuffer 是线程安全的,但它的性能较差,而 StringBuilder 是非线程安全的,但它的性能较好。修改建议:使用 StringBuilder 替代 StringBuffer。 代码举例: ```...

    JAVA面试资料大全-整理.zip

    9、 String、StringBuffer、StringBuilder 的区别 10、 同步和异步有何异同,在什么情况下分别使用他们?举例说明。 .............................................. ...............................................

    java面试题

    3. **String与StringBuilder/StringBuffer的区别**: - **String**:不可变对象,每次修改都会创建新对象,不适合大量修改操作。 - **StringBuilder/StringBuffer**:可变对象,允许在原对象基础上修改,...

    文字复制替换

    因此,当我们进行文本操作时,通常会使用`String`的内置方法或`StringBuilder`、`StringBuffer`类。 1. **查找指定字符串**:在Java中,我们可以使用`indexOf()`方法来查找指定字符串。例如,如果我们要找到一段...

    44条Java代码优化建议

    因为每次使用String连接都会创建新的String对象,而StringBuilder和StringBuffer在内部是以数组的方式存储字符串,仅在必要时才进行数组扩容操作,从而减少垃圾回收的次数。 3. 局部变量的使用 尽可能地使用局部...

    java程序员面试题3---java华为面试题.

    - 在多线程环境中,StringBuffer是线程安全的,而StringBuilder不是,但在单线程环境下StringBuilder效率更高。 5. **运行时异常与一般异常有何异同?** - 运行时异常是程序设计或逻辑错误,如空指针异常、数组...

    面试问题大全

    为了提高性能,可以使用`StringBuilder`或`StringBuffer`。 2. **int 和 Integer 的区别** - **原始类型 vs 封装类型**:`int`是原始类型,而`Integer`是`int`的封装类型。 - **使用场景**:在集合中存储整数时,...

    Java面试宝典Beta5.0.pdf

    - 在循环中使用“+”连接字符串通常比使用StringBuilder或StringBuffer性能更差,因为会生成很多临时的String对象。 ### 第六章 Java的数据类型 1. **基本数据类型** - Java的基本数据类型包括byte、short、int...

    java面试大全,绝对全面

    在需要频繁修改字符串时,应使用`StringBuilder`或`StringBuffer`而非`String`。 3. **异常处理**: - 异常是程序运行时的非正常状态。运行时异常是常见的错误,如除零错误。Java编译器要求显式处理非运行时异常,...

    huawei面试题--java篇

    3. **性能**:在单线程环境中,频繁修改字符串时,`StringBuilder`(`StringBuffer`的非线程安全版本)相比`StringBuffer`更高效,因为后者每次调用方法都要进行加锁和解锁。 #### 五、运行时异常与一般异常的异同 ...

    java面试题技术类和人事面试问比较难回答的问题

    5. **颠倒字符串**:可以使用StringBuilder或StringBuffer的reverse()方法来高效地颠倒字符串。 6. **int 和 Integer 的区别**:int 是基本数据类型,直接存储值,而 Integer 是其包装类,是对象,可以进行null值...

    华为中兴通讯公司面试题

    - `StringBuffer`在多线程环境中是同步的,因此比`StringBuilder`更安全但效率较低。 5. **运行时异常与一般异常的异同:** - **相同点**:异常都是程序执行过程中可能发生的错误情况。 - **不同点**: - 运行...

    java面试宝典

    - **StringBuffer** 和 **StringBuilder**:可变,适合大量修改操作。 - **StringBuffer**:线程安全。 - **StringBuilder**:非线程安全,性能更高。 **35. 如何把一段逗号分割的字符串转换成一个数组?** 可以...

    java 程序员面试常见题目

    这条语句创建了 3 个 `String` 对象和 1 个 `StringBuilder` 或 `StringBuffer` 对象(取决于编译器优化)。 **38. try{} 里有一个 return 语句,那么紧跟在这个 try 后的 finally{} 里的 code 会不会被执行,什么...

Global site tag (gtag.js) - Google Analytics