常量字符串的连接 VS StringBuffer

3
"What arguments can you give for the use of one or another variant that is better, faster, or more correct?"
"第一个变体: "
StringBuffer sql = new StringBuffer("SELECT DISTINCT f.ID ")
    .append("FROM FIRST_TABLE F ")
        .append("LEFT JOIN SECOND_TABLE s ON f.ID = s.F_ID ")
    .append("WHERE ")
        .append("F.BOOL = 1 ")
        .append("AND S.DATE IS NOT NULL ")
        .append("AND S.CLOSED = 0 ");

第二种变体:

String sql = "SELECT DISTINCT f.ID " +
             "FROM FIRST_TABLE F " +
                "LEFT JOIN SECOND_TABLE s ON f.ID = s.F_ID " +
             "WHERE "
                "F.BOOL = 1 " +
                "AND S.DATE IS NOT NULL " +
                "AND S.CLOSED = 0";

*注:类String类StringBuffer


2个回答

11

第二种方法更好:

  • 它更清晰(更多的代码与您想要的内容有关)
  • 它更高效,因为所有连接操作都是在编译时完成的

即使需要执行时连接(例如您在其中使用了一个变量),编译后的代码也会在需要时使用StringBuilderStringBuffer(取决于您所针对的Java版本)。

请注意,如果您正在执行数据库查询,则效率将极其微不足道。


好的,谢谢。但是关于性能方面呢?这个问题最让人感兴趣。 - old
3
@GanGnaMStYleOverFlowErroR:不会的,事实上,在这种情况下,它会生成更少的字符串,因为(第三次)串联会在编译时完成。而且,即使不是这样,编译器也会处理正确的事情。请阅读http://www.yoda.arachsys.com/java/strings.html ,如果您有具体的情况,请编译并使用javap查看实际发生的情况。 - Jon Skeet
1
@enjoyLife:不,您仍将使用StringBufferStringBuilder获取字符串常量。如果您在单个表达式中提供所有内容,请阅读早期评论中的链接...如果您提供所有内容,则使用连接至少是同样有效的。对于像循环这样的操作,StringBuilder更好,因为您无法在单个表达式中表达整个操作。 - Jon Skeet
1
仅仅因为直接使用StringBuilder更复杂并不会使其更有效率。使用+要么在编译时简化,要么用更少的代码做完全相同的事情。无论如何,无论生成的字符串有多大,与传递、解析和执行SQL的成本相比,它都不太可能起到作用。 - Peter Lawrey
1
@enjoyLife:使用字符串连接,编译器可以在编译时完成它所能做的工作,并在执行时使用 StringBuilder 完成其余部分。因此,它至少与其他方法一样高效,并且更易读。 - Jon Skeet
显示剩余9条评论

0

你不应该浪费时间担心如何连接几个字符串。使用 2 并保持清晰。如果你认为这是一个伟大的程序员标志,那就错了,使用 StringBuilder/buffer。

要关注模糊定义的需求和进度落后的事情。

试试这个 ->

long finalTime1 = 0; { long initialTimeTest = System.currentTimeMillis(); for( int index = 0; index < 10000; index++ ){ StringBuilder sb = new StringBuilder("Hello, ").append("World"); System.out.println(sb.toString()); } finalTime1 = System.currentTimeMillis() - initialTimeTest;

}

long finalTime2 = 0; { long initialTimeTest = System.currentTimeMillis(); for( int index = 0; index < 10000; index++ ){ String sb = "Hello, " + "World"; System.out.println( sb ); } finalTime2 = System.currentTimeMillis() - initialTimeTest; }

System.out.println( finalTime1 ); System.out.println( finalTime2 );

结果:

... Hello, World Hello, World 245 148

你认为字符串缓冲区更快吗?

你正在违反所有规则的母亲:保持简单。-

对于平凡的字符串处理,没有理由使用StringBuilder。它只会给平凡的任务增加不必要的复杂性。

我们需要思考大局,思考模块对项目的整体业务影响。讨论我们是否应该使用StringBuilder/Builder或String来组装一些字符串是小打小闹的事情,不要这样做。

关于性能问题,我建议:http://cfd.gmu.edu/~jcebral/academics/csi702/notes/02-optimization.pdf


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接