StringBuffer中delete与setLength清空字符串效率比较
2019-02-25 18:55 无腿鸟 阅读(1869) 评论(0) 编辑 收藏 举报问题:
StringBuffer中有delete、setLength两个方法可以快速清空字符数组。哪个效率高呢?
结论:从清空字符串角度看,两者效率都很高,比较来看,setLength效率更高。
分析如下:
这两个函数都是继承自AbstractStringBuilder类。函数原型如下:
public AbstractStringBuilder delete(int start, int end) ; public void setLength(int newLength) ;
delete(int start, int end)删除了start、end之间的字符,并返回新的字符串。
setLength(int newLength)重新设置了字符长度,如果newLength比原长度大,则新增的空间赋值为‘\0’。
两者用途不同,却都可以用于清空字符串。delete(0,AbstractStringBuilder.length) 与setLength(0)可以达到相同的效果。
比较其源代码之后,发现setLength(0)在清空代码时只是对长度做了 一次赋值,setLength除了对长度赋值外,还做了一次代码copy操作。多执行的代码如下:
System.arraycopy(value, start+len, value, start, count-end);
因为count = end;所以这个copy应该也不会执行。但是delete函数多做了一些判断,效率上回比setLength低一点。不过delete多出的条件判断对性能的影响是微乎其微的,通过代码测试没有明显的差异,两者在清空字符串时效率都非常高。
另外,这个两个函数虽然可以将字符串清空,但并没有将资源回收,也就是说并没有达到回收资源的效果,因为AbstractStringBuilder 的字符数组仍在内存中,只不过我们人为将数组的有效长度置位了0,数组所占的资源并没有及时释放,只能等java的垃圾回收进行释放。
Jdk1.8源代码如下(jdk1.6与之类似,以上结论不变)
public AbstractStringBuilder delete(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) end = count; if (start > end) throw new StringIndexOutOfBoundsException(); int len = end - start; if (len > 0) { System.arraycopy(value, start+len, value, start, count-end); count -= len; } return this; } public void setLength(int newLength) { if (newLength < 0) throw new StringIndexOutOfBoundsException(newLength);
ensureCapacityInternal(newLength); if (count < newLength) { Arrays.fill(value, count, newLength, '\0'); } count = newLength; }
测试代码:
package myString; public class TestMain { public static void main(String[] args) { testStringBufferclear(); } private static void testStringBufferclear() { StringBuffer sbf = new StringBuffer("wwwwww"); StringBuffer sbi = new StringBuffer("wwwwww"); int count = 1000000; long start ; long end; StringBuffer sbftest = new StringBuffer(); for(int i = 0; i < 1000; i++) { sbftest.append("1234567890"); } String str = sbftest.toString(); start = System.currentTimeMillis(); for (int i = 0; i < count; i++) { sbi.append(str); sbi.setLength(0); } end = System.currentTimeMillis(); System.out.println("StringBuffer--setLength:" + (end - start));
start = System.currentTimeMillis(); for (int i = 0; i < count; i++) { sbf.append(str); sbf.delete(0, sbf.length()); } end = System.currentTimeMillis(); System.out.println("StringBuffer--delete:" + (end - start));
start = System.currentTimeMillis(); for (int i = 0; i < count; i++) { sbf.append(str); sbf = new StringBuffer("123431431"); } end = System.currentTimeMillis(); System.out.println("StringBuffer--new StringBuffer:" + (end - start)); } }
测试结果:
StringBuffer--setLength:674 StringBuffer--delete:689 StringBuffer--new StringBuffer:4108