字符串,StringBuffer的,和StringBuilder之间的性能和简便的权衡 [英] Performance and simplicity tradeoffs between String, StringBuffer, and StringBuilder

查看:129
本文介绍了字符串,StringBuffer的,和StringBuilder之间的性能和简便的权衡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你有没有想过在Java编程语言这一变化的含义是什么?

Have you ever thought about the implications of this change in the Java Programming Language?

String类被认为是一个不可变类(这一决定是故意深思熟虑的)。但字符串连接实在是太慢了,我已经基准它自己。所以StringBuffer的诞生。真正伟大的阶级,同步,真快。但有些人不乐意用一些synchronized块的性能开销,而StringBuilder的介绍。

The String class was conceived as an immutable class (and this decision was intentionally thought-out). But String concatenation is really slow, I've benchmarked it myself. So the StringBuffer was born. Really great class, synchronized and really fast. But some people were not happy with the performance cost of some synchronized blocks, and the StringBuilder was introduced.

不过,使用时的字符串来连接没有太多的对象,类的不变性使得它一个非常自然的方式来实现线程安全。我能理解使用StringBuffer当我们要管理多个字符串。但是,这是我的第一个问题:

But, when using String to concatenate not too many objects, the immutability of the class makes it a really natural way to achieve thread-safety. I can understand the use of StringBuffer when we want to manage several Strings. But, here is my first question:


  1. 如果您有要追加,比方说,10个或更少的字符串,例如,你会简单的贸易在执行时间只是一些毫秒?

我StringBuilder的基准太。它比StringBuffer的(仅有10%的改善)更有效。但是,如果在你的单线程程序你使用StringBuilder的,会发生什么,如果你有时候想改变设计使用多个线程?你要改的StringBuilder的每一个实例,如果你忘了一个,你就会有一些奇怪的效果(考虑可能出现的竞争条件),可以生产。

I've benchmarked StringBuilder too. It is more efficient than StringBuffer (just a 10% improvement). But, if in your single-threaded program you're using StringBuilder, what happens if you sometimes want to change the design to use several threads? You have to change every instance of StringBuilder, and if you forget one, you'll have some weird effect (given the race condition that may arise) that can be produced.

在这种情况下,你会换性能的调试?小时

好吧,这就是全部。除了简单的问题(StringBuffer的比+和线程安全更高效,和StringBuilder比StringBuffer的速度更快,但没有线程安全的),我想知道什么时候使用它们。

Ok, that's all. Beyond the simple question (StringBuffer is more efficient than "+" and thread-safe, and StringBuilder is faster than StringBuffer but no thread-safe) I would like to know when to use them.

(注意:我知道它们之间的区别,这是与平台相关的一些设计决策的结构问题)

(Important: I know the differences between them; this is a question related to the architecture of the platform and some design decisions.)

推荐答案

目前双方的StringBuffer和Builder那种无用的(从性能的角度来看)。
我解释为什么:

Nowadays both StringBuffer and Builder are sort of useless (from performance point of view). I explain why:

StringBuilder的应该是比StringBuffer的,但任何理智的JVM可以更快地优化掉的同步。所以这是非常,当它被引入了一个巨大的思念(小命中)。

StringBuilder was supposed to be faster than StringBuffer but any sane JVM can optimize away the synchronization. So it was quite a huge miss (and small hit) when it was introduced.

StringBuffer的使用未复制的char []创建的字符串(非共享变量)的时候;然而,这是问题的主要来源,包括漏水巨大的char []为小弦。在1.5,他们决定焦炭的副本[]必须发生每次和,实际上做无用的StringBuffer(同步在那里,以确保没有线程游戏可以欺骗出字符串)。这节省内存,虽然最终帮助GC(的明显减少足迹旁),通常的char []是耗内存对象的TOP3。

StringBuffer used NOT to copy the char[] when creating the String (in non shared variant); however that was a major source of issues, incl leaking huge char[] for small Strings. In 1.5 they decided that a copy of the char[] must occur every time and that practically made StringBuffer useless (the sync was there to ensure no thread games can trick out the String). That conserves memory, though and ultimately helps the GC (beside the obviously reduced footprint), usually the char[] is the top3 of the objects consuming memory.

String.concat是,现在仍然是连接两个字符串(只有2 ...或可能3)的最快方式。记住这一点,它不执行的char []的额外副本。

String.concat was and still is the fastest way to concatenate 2 strings (and 2 only... or possibly 3). Keep that in mind, it does not perform an extra copy of the char[].

回到无用的部分,现在任何第三方code可以达到同样的性能的StringBuilder。即使在java1.1我曾经有一个类名AsycnStringBuffer它做什么现在StringBuilder的不完全一样,但仍比分配StringBuilder的更大的char []。无论StrinBuffer / StringBuilder的是默认情况下为小弦优化,你可以看到C-TOR

Back to the useless part, now any 3rd party code can achieve the same performance as StringBuilder. Even in java1.1 I used to have a class name AsycnStringBuffer which did exactly the same what StringBuilder does now, but still it allocates larger char[] than StringBuilder. Both StrinBuffer/StringBuilder are optimized for small Strings by default you can see the c-tor

  StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
    }

因此​​,如果第二个字符串比16chars时间越长,它得到了根本的另一个副本
的char []。 pretty酷。

Thus if the 2nd string is longer than 16chars, it gets another copy of the underlying char[]. Pretty uncool.

这可以在32位操作系统都拟合的StringBuilder /缓冲器和的char []到相同的高速缓存行(在x86上)是尝试的副作用......但我不知道。

That can be a side effect of attempt at fitting both StringBuilder/Buffer and the char[] into the same cache line (on x86) on 32bit OS... but I don't know for sure.

至于调试的时间此言等运用你的判断力,我个人不记得曾经遇到的任何问题瓦特/字符串操作,除了implement执行。绳索都结构JDO implement执行的SQL生成。

As for the remark of hours of debugging, etc. Use your judgment, I personally do not recall ever having any issues w/ strings operations, aside impl. rope alike structure for the sql generator of JDO impl.

编辑:
下面我说明一下在java设计人员没有尽到做字符串操作速度更快。
请注意,类用于java.lang包,它只能通过将其添加到引导类路径放在那里。然而,即使不放在那里(所不同的是code一行!),这将会是仍快于StringBuilder的,令人震惊?该类会作出字符串1 +字符串2 + ...很多比使用StringBuilder的好,但也...

Below I illustrate what java designers didn't do to make String operations faster. Please, note that the class is intended for java.lang package and it can put there only by adding it to the bootstrap classpath. However, even if not put there (the difference is a single line of code!), it'd be still faster than StringBuilder, shocking? The class would have made string1+string2+... a lot better than using StringBuilder, but well...

package java.lang;

public class FastConcat {

    public static String concat(String s1, String s2){
        s1=String.valueOf(s1);//null checks
        s2=String.valueOf(s2);

        return s1.concat(s2);
    }

    public static String concat(String s1, String s2, String s3){
        s1=String.valueOf(s1);//null checks
        s2=String.valueOf(s2);
        s3=String.valueOf(s3);
        int len = s1.length()+s2.length()+s3.length();
        char[] c = new char[len];
        int idx=0;
        idx = copy(s1, c, idx);
        idx = copy(s2, c, idx);
        idx = copy(s3, c, idx);
        return newString(c);
    }
    public static String concat(String s1, String s2, String s3, String s4){
        s1=String.valueOf(s1);//null checks
        s2=String.valueOf(s2);
        s3=String.valueOf(s3);
        s4=String.valueOf(s4);

        int len = s1.length()+s2.length()+s3.length()+s4.length();
        char[] c = new char[len];
        int idx=0;
        idx = copy(s1, c, idx);
        idx = copy(s2, c, idx);
        idx = copy(s3, c, idx);
        idx = copy(s4, c, idx);
        return newString(c);

    }
    private static int copy(String s, char[] c, int idx){
        s.getChars(c, idx);
        return idx+s.length();

    }
    private static String newString(char[] c){
        return new String(0, c.length, c);
        //return String.copyValueOf(c);//if not in java.lang
    }
}

这篇关于字符串,StringBuffer的,和StringBuilder之间的性能和简便的权衡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆