10

What would be the difference between Java 1.4.2's implementation of replace, and Apache 2.3's implementation? Is there a performance gain one over another?

Java 1.4.2 replace

Apache 2.3 replace

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Oh Chin Boon
  • 23,028
  • 51
  • 143
  • 215
  • Is there a specific reason you're asking about an ancient Java version? – Joachim Sauer Aug 10 '11 at 14:05
  • Hi Jochim, im stucked with an ancient Java version i must maintain. :( – Oh Chin Boon Aug 10 '11 at 14:20
  • Note that `String.replace(CharSequence, CharSequence)` uses regexp internally. :( See http://stackoverflow.com/questions/16228992/commons-lang-stringutils-replace-performance-vs-string-replace – Vadzim Dec 02 '13 at 17:52

6 Answers6

18

The String.replace() method you linked to takes two char values, so it only ever replaces on character with another (possibly multiple times, 'though).

The StringUtils.replace() method on the other hand takes String values as the search string and replacement, so it can replace longer substrings.

The comparable method in Java would be replaceAll(). replaceAll() is likely to be slower than the StringUtils method, because it supports regular expressions and thus introduces the overhead of compiling the search string first and running a regex search.

Note that Java 5 introduced String.replace(CharSequence, CharSequence) which does the same thing as StringUtils.replace(String,String) (except that it throws a NullPointerException if any of its arguments are null). Note that CharSequence is an interface implemented by String, so you can use plain old String objects here.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • 2
    +1 for pointing out that java.lang.String.replaceAll(...) uses regex and it is slow. The algorithm used by StringUtils.replace(...) is far superior and outperforms replaceAll() – Drupad Panchal Aug 10 '11 at 14:05
  • @JoachimSauer, the answer at http://stackoverflow.com/a/4874768/910201 mentions `.replaceEach()`, but where is it coming from? I do not have access to such a method and I've tried importing `org.springframework.util.StringUtils`, `org.apache.soap.util.StringUtils`, `org.apache.axis.utils.StringUtils`, and `com.ibm.wsdl.util.StringUtils`. – Xonatron Feb 21 '12 at 17:57
  • @MatthewDoucette: the answer is in the comments of the answer you linked to: Apache Commons-Lang `StringUtils` since Version 2.4. – Joachim Sauer Feb 21 '12 at 18:18
3
public class Compare {

    public static void main(String[] args) {
        StringUtils.isAlphanumeric(""); // Overhead of static class initialization for StringUtils
        String key = "0 abcdefghijklmno" + Character.toString('\n') + Character.toString('\r');

        String key1 = replace1(key);
        String key2 = replace2(key);
    }


    private static String replace1(String key) {
        long start = System.nanoTime();
        key = StringUtils.replaceChars(key, ' ', '_');
        key = StringUtils.replaceChars(key, '\n', '_');
        key = StringUtils.replaceChars(key, '\r', '_');
        long end = System.nanoTime() - start;
        System.out.println("Time taken : " + end);
        return key;
    }

    public static String replace2(String word) {
        long start = System.nanoTime();
        char[] charArr = word.toCharArray();

        int length = charArr.length;
        for (int i = 0; i < length; i++) {
            if (charArr[i] == ' ' || charArr[i] == '\n' || charArr[i] == '\r') {
                charArr[i] = '_';
            }
        }

        String temp = new String(charArr);
        long end = System.nanoTime() - start;
        System.out.println("Time taken : " + end);
        return temp;
    }
}

Time taken : 6400

Time taken : 5888

Times are almost the same!

I've edited the code to drop out overheads of replace2 which were not because of JDK implementation.

Amir Pashazadeh
  • 7,170
  • 3
  • 39
  • 69
sreenath V
  • 121
  • 1
  • 1
2

1.4.2 replaces operates only with char arguments whereas the Apache 2.3 one takes in strings.

adarshr
  • 61,315
  • 23
  • 138
  • 167
1
  • String.replace(char, char) can't replace whole strings
  • you can have null values with StringUtils.replace(..).

String.replace(CharSequence s1, CharSequence s2) will do the same thing if the first string is not-null. Otherwise it will throw a NullPointerException

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
0

To replace a string character with another string using StringUtil.Replace, I tried following and it's working fine for me to replace multiple string values from a single string.

String info = "[$FIRSTNAME$]_[$LASTNAME$]_[$EMAIL$]_[$ADDRESS$]";

String replacedString = StringUtil.replace(info, new String[] { "[$FIRSTNAME$]","[$LASTNAME$]","[$EMAIL$]","[$ADDRESS$]" }, new String[] { "XYZ", "ABC" ,"abc@abc.com" , "ABCD"});

This will replace the String value of info with newly provided value...

Dylan Slabbinck
  • 846
  • 1
  • 16
  • 27
0

Apache's is quite a bit faster, if I recall correctly. Recommended.

Brian
  • 6,391
  • 3
  • 33
  • 49
  • how is it faster? Do you have benchmark or algorithm analysis? – Bozho Aug 10 '11 at 14:24
  • I used it in a project after having done benchmarks, yes. I no longer have them though. Thinking about it, if it wasn't better, why would they develop it? Who's going to add a slower `replace()` option to the String Utils project? :-) – Brian Aug 10 '11 at 14:26
  • 1
    in 1.4.2 there wasn't a `String.replace(string, string)`. So it was needed in commons. Then 1.5 added it. – Bozho Aug 10 '11 at 14:31
  • Fair enough; my answer is based on having tested Java 6 string replacement generally against StringUtils string replacement, in which StringUtils fared substantially better. – Brian Aug 10 '11 at 14:39
  • I think it was 30% - 50% faster, quite impressive. Was nearly 18 months ago though so I might be wildly out! – Brian Aug 10 '11 at 15:00