是String.trim()比String.replace()快吗?

时间:2018-06-29 22:26:31

标签: java

假设有一个类似" world "的字符串。此字符串的开头和结尾只有空格。 trim()replace()快吗?

我曾经使用过一次替换,我的导师说不要使用它,因为trim()可能更快。

如果没有,trim()replace()有什么优势?

5 个答案:

答案 0 :(得分:8)

如果我们查看source code中的方法:

replace()

 public String replace(CharSequence target, CharSequence replacement) {
    String tgtStr = target.toString();
    String replStr = replacement.toString();
    int j = indexOf(tgtStr);
    if (j < 0) {
        return this;
    }
    int tgtLen = tgtStr.length();
    int tgtLen1 = Math.max(tgtLen, 1);
    int thisLen = length();
    int newLenHint = thisLen - tgtLen + replStr.length();
    if (newLenHint < 0) {
        throw new OutOfMemoryError();
    }
    StringBuilder sb = new StringBuilder(newLenHint);
    int i = 0;
    do {
        sb.append(this, i, j).append(replStr);
        i = j + tgtLen;
    } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);
    return sb.append(this, i, thisLen).toString()
}

对比trim()

public String trim() {
    int len = value.length;
    int st = 0;
    char[] val = value;    /* avoid getfield opcode */
    while ((st < len) && (val[st] <= ' ')) {
        st++;
    }
    while ((st < len) && (val[len - 1] <= ' ')) {
        len--;
    }
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}

如您所见,replace()调用了多个其他方法并在整个String中进行迭代,而trim()只是在String的开头和结尾进行迭代,直到字符不是空格。因此,就尝试仅 删除单词前后的空白而言,trim()效率更高。


我们可以对此进行一些基准测试:

public static void main(String[] args) {
       long testStartTime = System.nanoTime();;
       trimTest();
       long trimTestTime = System.nanoTime() - testStartTime;
       testStartTime = System.nanoTime();     
       replaceTest();
       long replaceTime = System.nanoTime() - testStartTime;           
       System.out.println("Time for trim(): " + trimTestTime);
       System.out.println("Time for replace(): " + replaceTime);            
}

public static void trimTest() {
    for(int i = 0; i < 1000000; i ++) {     
        new String("  string   ").trim();
    }
}
public static void replaceTest() {
    for(int i = 0; i < 1000000; i ++) {     
        new String("  string   ").replace(" ", "");
    }
}

输出:

Time for trim(): 53303903
Time for replace(): 485536597
//432,232,694 difference

答案 1 :(得分:4)

trim()肯定是更快键入,是的。它不带任何参数。

了解您要去哪里做什么也更快。您试图修剪字符串,而不是用空字符串替换其包含的所有空格,从其他上下文中得知,字符串的开头和结尾都只有空格< / em>。

无论您如何看,它的确要快得多。不要使试图阅读您的代码的人的生活复杂化。在大多数情况下,是几个月之后,或者至少是您不讨厌的人。

答案 2 :(得分:3)

假设编写Java库代码的人做得很好 1 ,则可以假设一个特殊目的的方法(如trim())将同样快,甚至可能更快比通用方法(例如replace(...))做同样的事情。

两个原因:

  • 如果专用方法较慢,则可以将其实现重写为对通用方法的等效调用,从而使性能在大多数情况下等效。有能力的程序员会这样做,因为它可以减少维护成本。

  • 在特殊用途方法中,可能会进行一些优化,而这些优化不适用于一般用途。

在这种情况下,我们知道trim()仅需要 来查看字符串的开头和结尾...而replace(...) 需要查看字符串中的所有字符。 (我们可以从相应方法的描述中推断出这一点。)

如果我们假设“胜任力”,那么我们可以推断出开发人员将进行分析,而未实现trim()欠佳的 2 ;也就是说,他们不会编码trim()来检查所有字符。


使用通用方法而不是通用方法还有另一个原因。它使您的代码更简单,更易于阅读,并且更易于检查正确性。这可能比性能更重要

这显然适用于trim()replace(...)的情况。


1-在这种情况下,我们可以。有很多人在看这段代码,很多人会大声抱怨性能过高的问题。

2-不幸的是,它并不总是那么简单。需要针对“典型”行为优化库方法,但是还需要避免在边缘情况下的病理表现。并非总是都能做到这两者。

答案 3 :(得分:1)

修剪将修剪外面的字符,直到它们不是空格为止。我相信它们会修剪空间,制表符和换行符。

替换将扫描整个字符串(因此,它可能是一个句子),并将内部的“”替换为“”,本质上将它们压缩在一起。

尽管它们有不同的用例,但明显的1是清理用户输入,而另一个是在找到匹配项的情况下更新字符串。

也就是说,运行时间:替换将在N次后运行,因为它将查找所有匹配的字符。修剪将以O(N)运行,但最有可能在每个末端减少几个字符。

修剪的想法我想是人们会输入的内容,但是在提交表单之前不小心按了空格,本质上是试图保存字段“ Foo”而不是“ Foo”

答案 4 :(得分:0)

s.trim()缩短了String s。这意味着不必将字符从索引移到另一个。它从s.toCharArray()[0]的第一个字符(String)开始,并逐个字符地缩短String字符,直到出现第一个非空白字符。其作用与缩短String的末尾相同。因此,它将压缩String。如果String没有开头和结尾的空格,则trim将在检查第一个和最后一个字符后准备就绪。

对于" world ".trim(),需要执行两个步骤:一个步骤是删除第一个索引中的第一个前导空白,而第二个步骤删除最后一个索引中的最后一个空白。

" world ".replace(" ", "")将至少需要n = " world ".length()个步骤。它必须检查每个字符是否必须替换。但是,如果考虑到String.replace(...)的实现需要编译Pattern,构建Matcher然后替换所有匹配的区域,与缩短{{ 1}}。

我们还必须考虑String不能代替空格,而只能代替" world ".replace(" ", "") String。由于" "使用String replace(CharSequence target, CharSequence replacement)编译目标,因此我们不能使用字符类 \ s 。为了更准确,我们必须将Pattern.LITERAL" world ".trim()进行比较。仍然不一样,因为" world ".replaceAll("\\s", "")中每个String trim()的{​​{1}}中的空白都定义为c <= ' '

总结:c应该更快-特别是对于长字符串

方法的工作方式说明基于Java 8中s.toCharArray()的实现。但是实现可以更改。

但是问题应该是:您打算对字符串做什么?您要修剪还是要替换某些字符?根据它使用相应的方法。