为什么js拼接字符串StringBuilder效率那么高
2013-07-31 08:13
351 查看
/article/1306674.html
大家都知道StringBuilder在拼接大量字符串的时候相对String来说具有很高的效率,这是由于StringBuilder在内部处理上使用了字符串的链式存储表示法(串的块链存储法)。串的块链存储结构的C代码是这样的:
由此,可以看到它同时具有线性表和链表的特性。我们可以类比的想象一下,把上面的代码改写成下面的C#代码:
其实上面的这段C#代码就是StringBuilder的一部分定义了,但StringBuilder中为了快速的获取到字符串的长度以及更方便的输出字符串,它保存了一个Offset字段,这个字段记录了所有后继结点(next)里ch的长度之和。明显头结点ch中字符的长度(非数组长度)与这个offset的和就是整个字符串的长度Length,这样显得更高效避免了遍历字符串求长度的开销。
当我们初始化StringBuilder的时候,在构造函数中允许我们传入capacity、maxcapacity以及string参数,capacity就是我们这里ch数组的长度,而maxcapacity是最大的可容下的字符串长度,也就是说Length的长度必须小于maxcapacity。随便说一句,capacity和maxcapacity的默认值分别是16和2147483647。
说了那么多原理性的东西,下面来看看一段使用StringBuilder添加字符串的代码,后面,我会使用图文来解析StringBuilder内部的工作方式。
下面我们分输入的情况来讨论:
1.如果input的长度小于等于3:
当strb的内部发现当前Append的字符串长度小于strb中chunck中剩余的长度,就会直接将输入字符串添加到末尾。
2.如果input的长度大于3:
如果input的长度大于strb中ch剩余长度的时候,那么就要对strb进行“断裂”了,也就是说将input前一部分的值放到strb中去,同时将input剩下的值放到新创建的StringBuilder(也就是next)当中。
请注意strb中和strbNew中的蓝色部分,这不是巧合相等,它们确实是相等的长度,在“断裂”后,系统会重新为strb分配存储空间,这个存储空间中空闲的部分恰恰就是没有断裂前chunck中的长度。我还必须说明的一点是,在“断裂”过后,还会重新设置strb的offset,这个offset实际上就是strbNew的长度而且这个是一个循环递归的过程,在下一次strb满的时候又会执行整个这个过程。
StringBuilder的整个过程就是一个串的块链存储法的实现,它也用到了数组拷贝,但是它是通过unsafe代码来实现的,所以性能相对于托管代码要高一点。
大家都知道StringBuilder在拼接大量字符串的时候相对String来说具有很高的效率,这是由于StringBuilder在内部处理上使用了字符串的链式存储表示法(串的块链存储法)。串的块链存储结构的C代码是这样的:
1 | #define CHUNKSIZE 80 |
2 | typedef struct Chunk |
3 | { |
4 | char ch[CHUNKSIZE]; |
5 | struct Chunk* next; |
6 | }Chunk; |
1 | class StringBuilder |
2 | { |
3 | private char [] ch; |
4 | private StringBuilder next; |
5 | } |
当我们初始化StringBuilder的时候,在构造函数中允许我们传入capacity、maxcapacity以及string参数,capacity就是我们这里ch数组的长度,而maxcapacity是最大的可容下的字符串长度,也就是说Length的长度必须小于maxcapacity。随便说一句,capacity和maxcapacity的默认值分别是16和2147483647。
说了那么多原理性的东西,下面来看看一段使用StringBuilder添加字符串的代码,后面,我会使用图文来解析StringBuilder内部的工作方式。
1 | //chuncksize=16,目前还有3个空闲 |
2 | var strb = new StringBuilder( "abcdefghijklm" ); |
3 | var input=Console.ReadLine(); |
4 | strb.Append(input); |
1.如果input的长度小于等于3:
当strb的内部发现当前Append的字符串长度小于strb中chunck中剩余的长度,就会直接将输入字符串添加到末尾。
2.如果input的长度大于3:
如果input的长度大于strb中ch剩余长度的时候,那么就要对strb进行“断裂”了,也就是说将input前一部分的值放到strb中去,同时将input剩下的值放到新创建的StringBuilder(也就是next)当中。
请注意strb中和strbNew中的蓝色部分,这不是巧合相等,它们确实是相等的长度,在“断裂”后,系统会重新为strb分配存储空间,这个存储空间中空闲的部分恰恰就是没有断裂前chunck中的长度。我还必须说明的一点是,在“断裂”过后,还会重新设置strb的offset,这个offset实际上就是strbNew的长度而且这个是一个循环递归的过程,在下一次strb满的时候又会执行整个这个过程。
StringBuilder的整个过程就是一个串的块链存储法的实现,它也用到了数组拷贝,但是它是通过unsafe代码来实现的,所以性能相对于托管代码要高一点。
相关文章推荐
- 为什么js拼接字符串StringBuilder效率那么高
- javascript模拟 C#中的StringBuilder,提升JS中字符串拼接的效率及性能
- js 字符串拼接方法,类似c#的StringBuilder
- java 字符串拼接为什么要用 StringBuilder 而不直接用 String 相加连接
- 为什么 Java 8 中不再需要 StringBuilder 拼接字符串
- 利用JS提高组合拼接字符串效率的方法
- js字符串拼接效率
- 为什么 Java 8 中不再需要 StringBuilder 拼接字符串
- 利用JS提高组合拼接字符串效率的方法
- js long类型的日期转成Date,字符串StringBuilder拼接
- 拼接字符串的效率问题(String,StringBuffer,StringBuilder对比)
- String, StringBuffer, StringBuilder拼接字符串的执行效率比较
- C#的StringBuilder 以及string字符串拼接的效率对照
- 通过class字节码了解StringBuilder拼接字符串效率高的原因
- 为什么Java 8中不再需要StringBuilder拼接字符串
- 利用JS提高组合拼接字符串效率的方法(转)
- 利用JS提高组合拼接字符串效率的方法
- 提高js拼接字符串效率--自定义StringBulider
- 利用JS提高组合拼接字符串效率的方法
- js的prototype扩展的一个例子,模仿C#的StringBuilder功能,数组组合字符串,效率大于+拼凑