Cod*_*ile 14 java string optimization stringbuilder android
我有一个需要修剪的StringBuilder对象(即所有空格字符/ u0020及以下从任一端删除).
我似乎无法在字符串生成器中找到可以执行此操作的方法.
这就是我现在正在做的事情:
String trimmedStr = strBuilder.toString().trim();
Run Code Online (Sandbox Code Playgroud)
这给出了所需的输出,但它需要分配两个字符串而不是一个.在字符串仍在StringBuilder中时,是否更有效地修剪字符串?
Zav*_*yan 25
您不应该使用deleteCharAt方法.
正如Boris指出的那样,deleteCharAt方法每次都会复制数组.Java 5中执行此操作的代码如下所示:
public AbstractStringBuilder deleteCharAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
System.arraycopy(value, index+1, value, index, count-index-1);
count--;
return this;
}
Run Code Online (Sandbox Code Playgroud)
当然,单凭推测还不足以选择一种优化方法而不是另一种方法,因此我决定在这个线程中计算3种方法:原始方法,删除方法和子字符串方法.
这是我为orignal测试的代码:
public static String trimOriginal(StringBuilder sb) {
return sb.toString().trim();
}
Run Code Online (Sandbox Code Playgroud)
删除方法:
public static String trimDelete(StringBuilder sb) {
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
}
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)
子串方法:
public static String trimSubstring(StringBuilder sb) {
int first, last;
for (first=0; first<sb.length(); first++)
if (!Character.isWhitespace(sb.charAt(first)))
break;
for (last=sb.length(); last>first; last--)
if (!Character.isWhitespace(sb.charAt(last-1)))
break;
return sb.substring(first, last);
}
Run Code Online (Sandbox Code Playgroud)
我执行了100次测试,每次都生成一个百万字符的StringBuffer,其中包含一万个尾随和前导空格.测试本身是非常基础的,但它可以很好地了解这些方法需要多长时间.
以下是对3种方法进行计时的代码:
public static void main(String[] args) {
long originalTime = 0;
long deleteTime = 0;
long substringTime = 0;
for (int i=0; i<100; i++) {
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
StringBuilder sb3 = new StringBuilder();
for (int j=0; j<10000; j++) {
sb1.append(" ");
sb2.append(" ");
sb3.append(" ");
}
for (int j=0; j<980000; j++) {
sb1.append("a");
sb2.append("a");
sb3.append("a");
}
for (int j=0; j<10000; j++) {
sb1.append(" ");
sb2.append(" ");
sb3.append(" ");
}
long timer1 = System.currentTimeMillis();
trimOriginal(sb1);
originalTime += System.currentTimeMillis() - timer1;
long timer2 = System.currentTimeMillis();
trimDelete(sb2);
deleteTime += System.currentTimeMillis() - timer2;
long timer3 = System.currentTimeMillis();
trimSubstring(sb3);
substringTime += System.currentTimeMillis() - timer3;
}
System.out.println("original: " + originalTime + " ms");
System.out.println("delete: " + deleteTime + " ms");
System.out.println("substring: " + substringTime + " ms");
}
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
original: 176 ms
delete: 179242 ms
substring: 154 ms
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,子串方法提供了对原始"双字符串"方法的非常轻微的优化.但是,删除方法非常慢,应该避免.
所以回答你的问题:你可以按照你在问题中建议的方式修剪StringBuilder.子串方法提供的非常轻微的优化可能不能证明多余的代码.
| 归档时间: |
|
| 查看次数: |
17097 次 |
| 最近记录: |