0

Basically given an int, I need to generate a String with the same length containing only the specified character. Related question here, but it relates to C# and it does matter what's in the String.

This question, and my answer to it are why I am asking this one. I'm not sure what's the best way to go about it performance wise.

Example

Method signature:

String getPattern(int length, char character);

Usage:

//returns "zzzzzz"
getPattern(6, 'z');

What I've tried

String getPattern(int length, char character) {
    String result = "";
    for (int i = 0; i < length; i++) {
        result += character;
    }
    return result;
}

Is this the best that I can do performance-wise?

Community
  • 1
  • 1
Jay
  • 18,959
  • 11
  • 53
  • 72
  • You should have used a char datatype for result and returned using new String, that gives much better performance, see the benchmarks in the answer below. – Rajeev Sreedharan Aug 29 '11 at 07:15

7 Answers7

6

You should use StringBuilder instead of concatenating chars this way. Use StringBuilder.append().

StringBuilder will give you better performance. The problem with concatenation the way you are doing is each time a new String (string is immutable) is created then the old string is copied, the new string is appended, and the old String is thrown away. It's a lot of extra work that over a period of type (like in a big for loop) will cause performance degradation.

CoolBeans
  • 20,654
  • 10
  • 86
  • 101
  • Yikes! all your answers came in so quickly (+1 to you all). This answer was first so I'll accept it (Thanks to the others as well!). This _does_ work in GWT (just tried it out) - I should have specified that as a requirement. – Jay Aug 29 '11 at 06:04
  • 1
    @Trevor Senior - We are super fast at StackOverflow even at 1 AM in the morning. You are welcome! – CoolBeans Aug 29 '11 at 06:06
  • 1
    Damn my slow typing! I blame the beer. – Brian Roach Aug 29 '11 at 06:13
  • 2
    @Brian Roach - LOL. I will give +1 for having beer on a Monday morning :P – CoolBeans Aug 29 '11 at 06:14
  • @CoolBeans - It's still Sunday night until I pass out go to sleep. – Brian Roach Aug 29 '11 at 06:26
  • 1
    True story: I once inherited a legacy process that I was told "uses a lot of CPU". It was burning up an entire core because of extensive logging doing exactly this. – Brian Roach Aug 29 '11 at 06:30
5

StringUtils from commons-lang or Strings from guava are your friends. As already stated avoid String concatenations.

StringUtils.repeat("a", 3) // => "aaa"
Strings.repeat("hey", 3) // => "heyheyhey"
4

Use primitive char arrays & some standard util classes like Arrays

public class Test {
    static String getPattern(int length, char character) {
        char[] cArray = new char[length];
        Arrays.fill(cArray, character);
//      return Arrays.toString(cArray);
        return new String(cArray);
    }

static String buildPattern(int length, char character) {
    StringBuilder sb= new StringBuilder(length);
    for (int i = 0; i < length; i++) {
        sb.append(character);
    }
    return sb.toString();
}

public static void main(String args[]){
    long time = System.currentTimeMillis();
    getPattern(10000000,'c');
    time = System.currentTimeMillis() - time;
    System.out.println(time);           //prints 93
    time = System.currentTimeMillis();
    buildPattern(10000000,'c');
    time = System.currentTimeMillis() - time;
    System.out.println(time);          //prints 188
}

}

EDIT Arrays.toString() gave lower performance since it eventually used a StringBuilder, but the new String did the magic.

Rajeev Sreedharan
  • 1,753
  • 4
  • 20
  • 30
  • This test is testing the creation of long strings. Could you test lots of short strings and see what the performance is? I'm interested if the array way is still faster. – Daniel Ryan Aug 29 '11 at 08:28
  • @Zammbi : lots of short strings? The snip here only serves for a char variable repeated n times. If you have Strings to concatenate then you should use a StringBuilder. Character sequences are simply not meant for the purpose. – Rajeev Sreedharan Aug 29 '11 at 08:55
  • What I mean you have c repeated 10000000 times. What if the test was c was repeated only about 4-10 times but the test was run 10000000 times. Though I guess it really doesn't matter, so don't worry about it. – Daniel Ryan Aug 29 '11 at 09:56
3

Yikes, no.

A String is immutable in java; you can't change it. When you say:

result += character;

You're creating a new String every time.

You want to use a StringBuilder and append to it, then return a String with its toString() method.

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
2

I think it would be more efficient to do it like following,

String getPattern(int length, char character) 
        {
            char[] list = new char[length];
            for(int i =0;i<length;i++)
            {
                list[i] = character;
            }
            return new string(list);
        }
Low Flying Pelican
  • 5,974
  • 1
  • 32
  • 43
1

Concatenating a String is never the most efficient, since String is immutable, for better performance you should use StringBuilder, and append()

String getPattern(int length, char character) {
    StringBuilder sb= new StringBuilder(length)
    for (int i = 0; i < length; i++) {
        sb.append(character);
    }
    return sb.toString();
}
amit
  • 175,853
  • 27
  • 231
  • 333
1

Performance-wise, I think you'd have better results creating a small String and concatenating (using StringBuilder of course) until you reach the request size: concatenating/appending "zzz" to "zzz" performs probably betters than concatenating 'z' three times (well, maybe not for such small numbers, but when you reach 100 or so chars, doing ten concatenations of 'z' followed by ten concatenations of "zzzzzzzzzz" is probably better than 100 concatenatinos of 'z').

Also, because you ask about GWT, results will vary a lot between DevMode (pure Java) and "production mode" (running in JS in the browser), and is likely to vary depending on the browser.

The only way to really know is to benchmark, everything else is pure speculation.
And possibly use deferred binding to use the most performing variant in each browser (that's exactly how StringBuilder is emulated in GWT).

Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164