I want to create a string which is made by concatenating about 3000 other strings.
I hear that using so many strings can be inefficient because they lie in some kind of
pool and may not be picked up by the GC immediately after they are not needed.
Is this the best way to go about it -
StringBuilder sb = new StringBuilder("");
for(String s : arrayWith3000Strings)
{
sb.append(s);
}
or should i concatenate all the strings into one string ?
This is definitely a case where StringBuilder is preferred.
Strings are "immutable". Any operation that modifies a string (including "append") creates a new string. Using stringbuilder avoids that expense.
This link (one of many) explains further:
http://javarevisited.blogspot.com/2011/07/string-vs-stringbuffer-vs-stringbuilder.html
Yes, Your code is good.
Even though you use String concatenation it creates new String objects because Strings are immutable.
StringBuffer has even better performance than StringBuilder, but StringBuffer is not thread-safe!
EDIT: of course, it is vice versa :)
Related
I need to modify the input string to return some output. Basically, when I see a particular string I need to remove it. I am thinking whether to use StringBuilder versus String. From my perspective, String would be much simpler.
Suppose:
StringBuilder input = new StringBuilder(inputs)
if(inputs.contains("someword)"")) {
// remove it by inputs = inputs.replace("someword", "");
}
Is it better to use StringBuilder input = new StringBuilder(inputs) and delete the particular string or use the original inputs = inputs.replace(...).
I think it will get messy to use StringBuilder. StringBuilder is used for concatentation, but I am not concentating strings.
In the past, StringBuilder was most times much faster than String when you applied multiple modifications to a String.
But since JDK 6, the compiler itself replaces String often automatically by StringBuilder (including all related lines) when this may improve the performance. This becomes visible by the use of a decompiler. So in most cases you won't notice any difference.
If you apply multiple operations to a string in a more complex structure than a simple batch of commands, then using StringBuilder is still better than the automatic compiler optimization.
II've been in the habit of doing:
int num = 12;
String text = ""+12;
for a long time, but I've found that to be a very inefficient mechanism for the large number of additions.
For those cases I generally do something like:
// this is psuedo code here..
FileInputStream fis = new FileInputStream(fis);
StringBuilder builder = new StringBuilder();
while(input.hasNext()) {
builder.append(input.nextString());
}
My question is: When coding for Android (vs the General Java case) Is the performance trade off at the small case worth using String Builder, or are there any other reasons to prefer String Builder in these small cases? It seems like it's a lot of extra typing int he simple case presented above. I also suspect (though I have not confirmed) that the memory allocations in the simple case are probably not worth it.
Edit: Suppose that the values being appended aren't known at compile time, I.E. they aren't constants.
Also the example above of ""+12 is a poorly chosen example.. Suppose it was
String userGeneratedText = textInput.getText().toString();
int someVal = intInput.getInt();
String finalVal = userGeneratedText+someVal;
If your code is short as you shown here:
String text = "foo" + 12;
The compiler will automatically replace the concatenation to use StringBuilder:
String text = new StringBuilder().append("foo").append(12).toString();
So don't worry about the inefficiency of this code, because it will work better than you expect.
For cases when you need to append very large Strings or you don't know how many objects (Strings, ints, booleans, etc) will you concatenate, use a StringBuilder as you do in your second code sample.
Here's a more in depth explanation about how the String concatenation works: http://blog.eyallupu.com/2010/09/under-hood-of-java-strings.html
As far as I know! string is immutable object. It means that its state cannot be changed, when ever you append value to string type then what happened is compiler deletes old one create new one with apended value.
But this is not the case with StringBuilder. StringBuilder is mutable which means its old value won't be destroyed. Any change/append will be taken place with existing object.
I know I am not covering in depth but this might cause major performance difference.
What is better
int i = 45;
String str = "dsfgdsgf"+i;
or
int i = 45;
String str = new StringBuilder().append("dsfgdsgf").append(i).toString();
I have read somewhere that StringBuilder is always better than concatenating strings
There is no difference in performance, as the compiler will internally convert the first version to the second one.
Since the first version is more readable you should use it when you concatenate a fixed number of items into a string.
Use StringBuilder when you append to a string many times, for example in a loop.
There shouldn't performance difference in both cases: prooflink. Compiler use StringBuilder implicitly to concatenate String.
Of course 1 case is much more readable than 2 in most cases.
Also no big differences in explicit casting of Integer values:
StringBuilder casting use AbstractStringBuilder#append(int) and explicit casting using String#valueOf(int) call Integer#toString(int) internaly.
If you are just concatenating values in a known format, consider:
int i = 45;
String str = String.format("%s%d", "dsfgdsgf", i);
Strings in Java are immutable objects. This means by writing String str = "dsfgdsgf"+i; you are actually creating a new String object and leave the old object for the Garbage Collector.
StringBuilder on the other hand is a mutable object so that the object is modified. Preferably you should use StringBuilder.append() or StringBuffer.append() whenever possible.
Note that StringBuilder is not synchronized, while StringBuffer is.
We should be using StringBuilder, if you are modifying a string many times by appending, removing etc.In you case, you are using StringBuilder and again converting it to String.I dont think you are saving much with the second approach,since you are creating a new StringBuilder object and appending and again converting it to String
Yes, StringBuilder is better than concatenating string. When you use following line of code String str = "dsfgdsgf"+i;
it uses StringBuilder internally. So you are just avoiding extra step by using StringBuilder directly.
Your second option is better because it's impossible to concatenate with a String; therefore the String must be converted first to a StringBuilder before doing the concatenation and then have the result converted back to a String.
This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 8 years ago.
When should we use + for concatenation of strings, when is StringBuilder preferred and When is it suitable to use concat.
I've heard StringBuilder is preferable for concatenation within loops. Why is it so?
Thanks.
Modern Java compiler convert your + operations by StringBuilder's append. I mean to say if you do str = str1 + str2 + str3 then the compiler will generate the following code:
StringBuilder sb = new StringBuilder();
str = sb.append(str1).append(str2).append(str3).toString();
You can decompile code using DJ or Cavaj to confirm this :)
So now its more a matter of choice than performance benefit to use + or StringBuilder :)
However given the situation that compiler does not do it for your (if you are using any private Java SDK to do it then it may happen), then surely StringBuilder is the way to go as you end up avoiding lots of unnecessary String objects.
I tend to use StringBuilder on code paths where performance is a concern. Repeated string concatenation within a loop is often a good candidate.
The reason to prefer StringBuilder is that both + and concat create a new object every time you call them (provided the right hand side argument is not empty). This can quickly add up to a lot of objects, almost all of which are completely unnecessary.
As others have pointed out, when you use + multiple times within the same statement, the compiler can often optimize this for you. However, in my experience this argument doesn't apply when the concatenations happen in separate statements. It certainly doesn't help with loops.
Having said all this, I think top priority should be writing clear code. There are some great profiling tools available for Java (I use YourKit), which make it very easy to pinpoint performance bottlenecks and optimize just the bits where it matters.
P.S. I have never needed to use concat.
From Java/J2EE Job Interview Companion:
String
String is immutable: you can’t modify a String object but can replace it by creating a new instance. Creating a new instance is rather expensive.
//Inefficient version using immutable String
String output = "Some text";
int count = 100;
for (int i = 0; i < count; i++) {
output += i;
}
return output;
The above code would build 99 new String objects, of which 98 would be thrown away immediately. Creating new objects is not efficient.
StringBuffer/StringBuilder
StringBuffer is mutable: use StringBuffer or StringBuilder when you want to modify the contents. StringBuilder was added in Java 5 and it is identical in all respects to StringBuffer except that it is not synchronised, which makes it slightly faster at the cost of not being thread-safe.
//More efficient version using mutable StringBuffer
StringBuffer output = new StringBuffer(110);
output.append("Some text");
for (int i = 0; i < count; i++) {
output.append(i);
}
return output.toString();
The above code creates only two new objects, the StringBuffer and the final String that is returned. StringBuffer expands as needed, which is costly however, so it would be better to initialise the StringBuffer with the correct size from the start as shown.
If all concatenated elements are constants (example : "these" + "are" + "constants"), then I'd prefer the +, because the compiler will inline the concatenation for you. Otherwise, using StringBuilder is the most effective way.
If you use + with non-constants, the Compiler will internally use StringBuilder as well, but debugging becomes hell, because the code used is no longer identical to your source code.
My recommendation would be as follows:
+: Use when concatenating 2 or 3 Strings simply to keep your code brief and readable.
StringBuilder: Use when building up complex String output or where performance is a concern.
String.format: You didn't mention this in your question but it is my preferred method for creating Strings as it keeps the code the most readable / concise in my opinion and is particularly useful for log statements.
concat: I don't think I've ever had cause to use this.
Use StringBuilder if you do a lot of manipulation. Usually a loop is a pretty good indication of this.
The reason for this is that using normal concatenation produces lots of intermediate String object that can't easily be "extended" (i.e. each concatenation operation produces a copy, requiring memory and CPU time to make). A StringBuilder on the other hand only needs to copy the data in some cases (inserting something in the middle, or having to resize because the result becomes to big), so it saves on those copy operations.
Using concat() has no real benefit over using + (it might be ever so slightly faster for a single +, but once you do a.concat(b).concat(c) it will actually be slower than a + b + c).
Use + for single statements and StringBuilder for multiple statements/ loops.
The performace gain from compiler applies to concatenating constants.
The rest uses are actually slower then using StringBuilder directly.
There is not problem with using "+" e.g. for creating a message for Exception because it does not happen often and the application si already somehow screwed at the moment. Avoid using "+" it in loops.
For creating meaningful messages or other parametrized strings (Xpath expressions e.g.) use String.format - it is much better readable.
I suggest to use concat for two string concatination and StringBuilder otherwise, see my explanation for concatenation operator (+) vs concat()
In my project there are some code snippets which uses StringBuffer objects, and the small part of it is as follows
StringBuffer str = new StringBuffer();
str.append("new " + "String()");
so i was confused with the use of append method and the + operator.
ie the following code could be written as
str.append("new ").append("String()");
So are the two lines above same?(functionally yes but) Or is there any particular usage of them? ie performance or readability or ???
thanks.
In that case it's more efficient to use the first form - because the compiler will convert it to:
StringBuffer str = new StringBuffer();
str.append("new String()");
because it concatenates constants.
A few more general points though:
If either of those expressions wasn't a constant, you'd be better off (performance-wise) with the two calls to append, to avoid creating an intermediate string for no reason
If you're using a recent version of Java, StringBuilder is generally preferred
If you're immediately going to append a string (and you know what it is at construction time), you can pass it to the constructor
Actually the bytecode compiler will replace all string concatenation which involve non constants in a Java program with invocations of StringBuffer. That is
int userCount = 2;
System.out.println("You are the " + userCount + " user");
will be rewritten as
int userCount = 2;
System.out.println(new StringBuffer().append("You are the ").append(userCount).append(" user").toString());
That is at least what is observable when decompiling java class files compiled with JDK 5 or 6. See this post.
The second form is most efficient in terms of performance because there is only one string object that is created and is appended to the stringbuffer.
The first form creates three string objects 1) for "new" 2)for "new String" 3) for the concatenated result of 1) and 2). and this third string object is concatenated to the string buffer.
Unless you are working with concurrent systems, use StringBuilder instead of StringBuffer. Its faster but not thread-safe :)
It also shares the same API so its more or less a straight find/replace-