1

大家好,我想问一下内存利用率和进程所需的时间。我有以下代码。我想优化我的代码,使其更快。字符串会占用更多内存吗?

public String replaceSingleToWord(String strFileText) {

    strFileText = strFileText.replaceAll("\\b(\\d+)[ ]?'[ ]?(\\d+)\"", "$1 feet $2  ");
    strFileText = strFileText.replaceAll("\\b(\\d+)[ ]?'[ ]?(\\d+)''", "$1 feet $2     inch");

    //for 23o34'
    strFileText = strFileText.replaceAll("(\\d+)[ ]?(degree)+[ ]?(\\d+)'", "$1 degree $3 second");

    strFileText = strFileText.replaceAll("(\\d+((,|.)\\d+)?)sq", " $1 sq");

    strFileText = strFileText.replaceAll("(?i)(sq. Km.)", " sqkm");
    strFileText = strFileText.replaceAll("(?i)(sq.[ ]?k.m.)", " sqkm");
    strFileText = strFileText.replaceAll("(?i)\\s(lb.)", " pound");
    //for pound
    strFileText = strFileText.replaceAll("(?i)\\s(am|is|are|was|were)\\s?:", "$1 ");
    return strFileText;
}

我认为这将需要更多的内存和时间我只是想降低复杂性。我只想减少处理我需要做的更改的时间和内存。replaceAll 功能有什么替代方法吗?我将如何最小化这段代码?让我变得更快并且内存利用率低?谢谢先进

4

4 回答 4

3

优化方法:

  • 每次更换时使用Pattern.compile()。创建一个类,创建模式字段,并且只编译一次模式。这样您将节省大量时间,因为每次调用时都会进行正则表达式编译replaceAll(),这是一项非常昂贵的操作
  • 使用非贪婪的正则表达式。而不是(\\d+)使用(\\d+?).
  • 如果可能的话尽量不使用正则表达式(lb.-> pound)?
  • 将多个具有相同替换的正则表达式合并为一个 - 适用于您的sqkmfeet替换
  • 可以尝试将您的 api 建立在StringBuilder; 然后使用addReplacement处理您的文本。

此外,您的许多replaces 中的一个点是未转义的。点匹配任何字符。使用\\..

课堂理念:

class RegexProcessor {
  private Pattern feet1rep = Pattern.compile("\\b(\\d+)[ ]?'[ ]?(\\d+)\"");
  // ...

  public String process(String org) {
    String mod = feet1rep.match(org).replaceAll("$1 feet $2  ");
    /...
  }
}
于 2013-10-14T12:36:10.117 回答
1

当需要对字符串进行大量修改时,使用 StringBuffer 和 StringBuilder 类。

与 Strings 类型的 StringBuffer 和 Stringbuilder 不同,对象可以一遍又一遍地修改,而不会留下许多新的未使用对象。

StringBuilder 类是从 Java 5 开始引入的,StringBuffer 和 StringBuilder 之间的主要区别在于 StringBuilders 方法不是线程安全的(不是同步的)。

建议尽可能使用 StringBuilder,因为它比 StringBuffer 快。但是,如果需要线程安全,最好的选择是 StringBuffer 对象。

public class Test{

    public static void main(String args[]){
       StringBuffer sBuffer = new StringBuffer(" test");
       sBuffer.append(" String Buffer");
       System.ou.println(sBuffer);  
   }
}




public class StringBuilderDemo {
    public static void main(String[] args) {
        String palindrome = "Dot saw I was Tod";

        StringBuilder sb = new StringBuilder(palindrome);

        sb.reverse();  // reverse it

        System.out.println(sb);
    }
}

因此,根据您的需要,您可以选择其中之一。

参考http://docs.oracle.com/javase/tutorial/java/data/buffers.html

于 2013-10-14T12:32:26.333 回答
1

就像 Joop Eggen 建议的那样,使用预编译模式和循环。将您的表达式组合在一起。例如,前两个可以写成

`"\\b(\\d++) ?' ?(\\d+)(?:''|\")"`

您可以以牺牲可读性为代价走得更远。所有替换的单个表达式也是可能的。

`"\\b(\\d++) ?(?:' ?(?:(\\d+)(?:''|\")|degree ?(\\d++)|...)"`

然后,您需要在诸如group(2) == null. 这很难维护,但是通过一个循环和巧妙编写的正则表达式,您将赢得比赛。:D


像 can't -> canot, should't -> should not 等单词的正则表达式是什么?

这取决于您想要的精确程度。最简单的方法是s.replaceAll("\\Bn't\\b", " not")。上述优化适用,所以不要replaceAll在性能很重要时使用。

一个通用的解决方案可能是这样的

Pattern SHORTENED_WORD_PATTERN =
    Pattern.compile("\\b(ca|should|wo|must|might)(n't)\\b");

String getReplacement(String trunk) {
    switch (trunk) { // needs Java 7
        case "wo": return "will not";
        case "ca": return "cannot";
        default: return trunk + " not";
    }
}

... relevant part of the replacer loop (see [replaceAll][])

    while (matcher.find()) {
        matcher.appendReplacement(result, getReplacement(matcher.group(1)));
    }

在 strFileText = strFileText.replace("á", "a"); 的情况下我该怎么办?strFileText = strFileText.replace("’", "\'"); strFileText = strFileText.replace("â€Â", "\'"); strFileText = strFileText.replace("ó", "o"); strFileText = strFileText.replace("é", "e"); strFileText = strFileText.replace("á", "a"); strFileText = strFileText.replace("ç", "c"); strFileText = strFileText.replace("ú", "u"); 如果我想用一行或其他方式写这个 replaceEach() 更适合这种情况

如果您追求效率,请注意以上所有字符串都以相同的字符开头Ã。单个正则表达式可能会á|’"|...比它慢得多Ã(ƒÂƒÃ‚¡|¢Â€Â™"|...)(除非正则表达式引擎可以自己优化它,目前情况并非如此)。

所以写一个正则表达式,其中所有常见的前缀都被提取并使用

String getReplacement(String match) {
    switch (match) { // needs Java 7
        case "á": return "a";
        case "’"": return "\\";
        ...
        default: throw new IllegalArgumentException("Unexpected: " + match);
    }
}

    while (matcher.find()) {
        matcher.appendReplacement(result, getReplacement(matcher.group()));
    }

也许 aHashMap可能比switch上述更快。

于 2013-10-14T13:05:42.010 回答
0

正则表达式模式可以在spots_[,.]?(而不是[ ]?)处得到改进。

Pattern在函数外使用已编译的静态 final 。

private static final Pattern PAT = Pattern.compile("...");


StringBuffer sb = new StringBuffer();
Matcher m = PAT.matcher(strFileText);
while (m.find()) {
    m.appendReplacement(sb, "...");
}
m.appendTail(sb);
strFileText = sb.toString();

在进行. if (m.find)_new StringBuffer

于 2013-10-14T12:35:14.550 回答