This question already has answers here:
String valueOf vs concatenation with empty string
(10 answers)
Closed 7 years ago.
I've had a few people tell me that things like this are super lazy:
int val = 5;
System.out.println("" + val);
String myStr = "" + val;
Why is this better than String.valueOf(val)? Isn't it doing the exact same thing under the hood?
It's not really "better", just shorter, making it easier to read and type. There is (virtually) no ther difference, even though a real purist might, probably, say, this is actually worse, because (at least, in the absence of optimization), this creates an intermediate StringBuilder object, that is then appended a character before being converted into a String, so, this may be spending more ticks, than .valueOf.
From JLS:
An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.
For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.
Related
This question already has answers here:
StringBuilder/StringBuffer vs. "+" Operator
(4 answers)
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 8 years ago.
In the past, I have been lead to believe that you should use StringBuilder and append(String) when building a string with variables, as opposed to string += split[i]. In what cases is this accurate? I ask because normally, if I was to write the following:
String[] split = args; // command line arguments or whatever
String myString = "";
for (int i = 0; i < split.length; i++) {
myString += split[i];
}
I am told by my IDE that it should be converted to use a StringBuilder instead. However, writing something like this:
StringBuilder build = new StringBuilder();
build.append("the ").append(build.toString()).append(" is bad").append(randomvar);
build.toString();
IntelliJ actually lists as a performance issue using a StringBuilder when I should be using a String. The fact that it's listed as a performance issue would indicate it could actually cause problems as opposed to just being a tiny bit slower.
I did notice that the first example is a loop and the second isn't - is a StringBuilder recommended for lots of concatenations but normal concatenation is better for non-looping situations (this also means in a loop the operator += would be used, whereas outside of a loop it could be "the " + build.toString() + " is bad" + randomVar - is += the problem as opposed to +?)
String concatenations are converted into calls to StringBuilder.append() behind the scenes.
String literal concatenations are (or at least can be) converted to individual String literals.
You're presumably using a String variable (not just two literals) inside the loop, so Java can't just replace that with a literal; it has to use a StringBuilder. That's why doing String concatenations in a loop should be done using a single StringBuilder, otherwise Java ends up creating another instance of StringBuilder every time the loop iterates.
On the other hand, something like this:
String animals = "cats " + "dogs " + "lizards ";
Will (or can be) replaced (by Java, not you) with a single String literal, so using a StringBuilder is actually counter-productive.
Beginning in java 1.5, the String + operator is translated into calls to StringBuilder.
In your example, the loop should be slower because the + operator creates a new StringBuilder instance each time through the loop.
The compiler will actually turn them both into the same form before compiling so neither will result in any performance difference. In this scenario you want to go with the shortest and most readable method available to you.
"An implementation may choose to perform conversion and concatenation
in one step to avoid creating and then discarding an intermediate
String object. To increase the performance of repeated string
concatenation, a Java compiler may use the StringBuffer class or a
similar technique to reduce the number of intermediate String objects
that are created by evaluation of an expression.
For primitive types, an implementation may also optimize away the
creation of a wrapper object by converting directly from a primitive
type to a string."
Source: http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.18.1.2
For little concats you can use the + operator with none issue. StringBuffer is indicated when we have large strings to be concatened, so with this class you can save memory and processor's time as well.
You can make a test trying to concat 1 million of words using + operator, and run the same teste using StringBuffer to see the different by yourself.
This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 9 years ago.
I understand that StringBuilder should be used for concatenating multiple strings rather than using +. My question is what is the cut off point?
I have been told that if concatenating 4 or more strings you should use the StringBuilder.append(), and for anything else, use +.
Is that the case? or is the point at which stringbuilder is more efficient more than 4?
As of Java 1.5, the compiler automatically uses StringBuilder when + is used in the source.
From the Javadoc for String:
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.
Zero.
Many years ago, in a Java version far far away (1.4), some people recommended replacing concatenation by StringBuffer (the thread-safe equivalent of StringBuilder, which had not been invented yet).
With the introduction of StringBuilder, and the redefinition of concatenation in terms of the faster StringBuilder, "optimized" code using StringBuffer incurred in unneeded synchronization, while non-optimal code with + was automatically enjoyed to the benefits of StringBuilder.
I would use StringBuilder when the concatenation is mixed with control structures or loops, or when I need to update some characters in the middle of the strings. Otherwise I assume that the compiler is smart enough to do a good job with the traditional concatenation.
Starting in jse 5, the + sign converts to a stringbuilder during compilation.
There is a caveat to this though, this:
String blam = a + b + c + d + e;
results in one stringbuilder and 5 appends (as expected)
This; however:
String blam = a;
blam += b + c;
blam := d + e;
results in 3 stringbuilders (one per line).
The point: + sign is fine, just stack it all in one line of code.
I would say that the compiler will substitute the plus with StringBuilder itself.
There are several situations you want to avoid in this case. For example using + in a loop. For each iteration a new StringBuilder will be created.
Might wanna read this question
The compiler is pretty good at optimizing this stuff, so usually, you won't gain much. But if you're doing concatenations in a loop for instance, you might gain some benefits from using a StringBuilder instead.
There is no defined answer because it's depends on JVM implementation. I use StringBuilder when I need to concat more than 3 strings.
I noticed a good case. When you need to concat static final String's you don't have to use StringBuilder. The compliler will concat it withour performance falling:
final class Example {
public static final String STRING_ONE = "string";
public static final String STRING_TWO = "string";
public static final String STRING_THREE = "string";
public static final String STRING_FOUR = "string";
public String getBigString() {
return STRING_ONE + STRING_TWO + STRING_THREE + STRING_FOUR;
}
}
Also I very interested in that question. I tryed to implement a good test and asked about that here.
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()
Is conversion to String in Java using
"" + <int value>
bad practice? Does it have any drawbacks compared to String.valueOf(...)?
Code example:
int i = 25;
return "" + i;
vs:
int i = 25;
return String.valueOf(i);
Update: (from comment)
And what about Integer.toString(int i) compared to String.valueOf(...)?
I would always prefer the String.valueOf version: mostly because it shows what you're trying to do. The aim isn't string concatenation - it's conversion to a string, "the string value of i".
The first form may also be inefficient - depending on whether the compiler spots what you're doing. If it doesn't, it may be creating a new StringBuffer or StringBuilder and appending the value, then converting it to a string.
Funnily enough, I have an article about this very topic - written years and years ago; one of the first Java articles on my web site, IIRC.
There is also Integer.toString(int i), which gives you the option of getting the string as a hex value as well (by passing a second param of 16).
Edit I just checked the source of String class:
public static String valueOf(int i) {
return Integer.toString(i, 10);
}
And Integer class:
public static String toString(int i, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
/* Use the faster version */
if (radix == 10) {
return toString(i);
}
...
If you call String.valueOf(i), it calls Integer.toString(i, 10), which then calls Integer.toString(i).
So Integer.toString(i) should be very slighty faster than String.valueOf(i), since you'd be cutting out two function calls. (Although the first function call could be optimized away by the compiler.)
Of course, a readability argument could still be made for String.valueOf(), since it allows you to change the type of the argument (and even handles nulls!), and the performance difference is negligible.
Definitely use String.valueOf(i).
Although I'm not sure of the optimizations on the compiler side, worst case scenario if you use "" + :
"" creates a new empty string.
"" + creates a StringBuilder (Java 1.5-16)
"" is appended to the StringBuilder, then
In other words, there is a lot of overhead that occurs if you use string addition. This is why it is not recommended to use the + operator on strings in loops. In general, always use Boolean.valueOf, Integer.valueOf, String.valueOf... etc, when possible. You'll save both on memory and on overhead.
Regardless of any performance considerations I think the first variant is really ugly. IMHO it's a shame that this kind of "dynamic casting" is even possible in Java.
Yes, it is IMHO a bad practice.
It would require to memory allocations (unless compiler and/or JIT optimize them). What's more, it will make less evident, what this code tries to do.
Personally I dislike the style of "" + i, but that is really a preference/coding standards thing. Ideally the compiler would optimize those into equivalent code (although you would have to decompile to see if it actually does), but technically, without optimization, "" + i is more inefficient because it creates a StringBuilder object that wasn't needed.
Right off the bat all I can think of is that in the your first example more String objects will be created than in the second example (and an additional StringBuilder to actually perform the concatenation).
But what you are actualy trying to do is create a String object from a int not concatenate a String with an int, so go for the:
String.valueOf(...);
option,
So yes your first option is bad practice!
I wonder what is best for static final variables contributing to compile-time constants:
public static final int VIEW_TYPE_LABEL_FIELD = 1;
public static final int VIEW_TYPE_HEADER_FIELD = ;
...
List <String[]> listViewInfo = new ArrayList<>();
listViewInfo.add(new String[]{"Label/Field view", String.valueOf(VIEW_TYPE_LABEL_FIELD)});
listViewInfo.add(new String[]{"Header/Field view", "" + VIEW_TYPE_LABEL_FIELD});
The compiler can potentially replace the String expressions with a constant. Is one or the other more recognizable as a compile-time constant? Maybe easier for the ("" + ..) construct?
This question already has answers here:
Closed 13 years ago.
Duplicate
java String concatenation
I'm curious what is the difference between the two.
The way I understand the string pool is this:
This creates 3 string objects in the string pool, for 2 of those all references are lost.
String mystr = "str";
mystr += "end";
Doesn't this also create 3 objects in the string pool?
String mystr = "str";
mystr = mystr.concat("end")
I know StringBuilder and StringBuffer are much more efficient in terms of memory usage when there's lots of concatination to be done. I'm just curious if there's any difference between the + operator and concat in terms of memory usage.
There's no difference in this particular case; however, they're not the same in general.
str1 += str2 is equivalent to doing the following:
str1 = new StringBuilder().append(str1).append(str2).toString();
To prove this to yourself, just make a simple method that takes two strings and +='s the first string to the second, then examine the disassembled bytecode.
By contrast, str1.concat(str2) simply makes a new string that's the concatenation of str1 and str2, which is less expensive for a small number of concatenated strings (but will lose to the first approach with a larger number).
Additionally, if str1 is null, notice that str1.concat(str2) throws a NPE, but str1 += str2 will simply treat str1 as if it were null without throwing an exception. (That is, it yields "null" concatenated with the value of str2. If str2 were, say, "foo", you would wind up with "nullfoo".)
Update: See this StackOverflow question, which is almost identical.
The important difference between += and concat() is not performance, it's semantics. concat() will only accept a string argument, but + (or +=) will accept anything. If the non-string operand is an object, it will be converted to a string by calling toString() on it; a primitive will be converted as if by calling the appropriate method in the associated wrapper class, e.g., Integer.toString(theInt); and a null reference becomes the string "null".
Actually, I don't know why concat() even exists. People see it listed in the API docs and assume it's there for a good reason--performance being the most obvious reason. But that's a red herring; if performance is really a concern, you should be using a StringBuilder, as discussed in the thread John linked to. Otherwise, + or += is much more convenient.
EDIT: As for the issue of "creating objects in the string pool," I think you're misunderstanding what the string pool is. At run-time, the actual character sequences, "str" and "end" will be stored in a dedicated data structure, and wherever you see the literals "str" and "end" in the source code, the bytecode will really contain references to the appropriate entries in that data structure.
In fact, the string pool is populated when the classes are loaded, not when the code containing the string literals is run. That means each of your snippets only creates one object: the result of the concatenation. (There's also some object creation behind the scenes, which is a little different for each of the techniques, but the performance impact is not worth worrying about.)
The way I understand the string pool
is this:
You seem to have a misconception concerning that term. There is no such thing as a "string pool" - the way you're using it, it looks like you just mean all String object on the heap. There is a runtime constant pool which contains, among many other things, compile-time String constants and String instances returned from String.intern()
Unless the argument to concat is an empty string, then
String mystr = "str";
mystr = mystr.concat("end")
will also create 3 strings.
More info: https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html.