Java - StringBuilder vs Concatenation of strings [duplicate] - java

This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 4 years ago.
The question is simple, what is better for avoiding of non-appropriated memory using? For example, let's say that we've a String s = "Test" and we'd like to add 1 to it so it becomes Test1. We all know that s gets a memory location and if we use StringBuilder, Test1 will get a new memory address or it'll remain at s's place, and what if we use concat?

One line concatenations are optimized and converted to StringBuilder under the hood. Memory wise is the same thing, but the manual concatenation is more concise.
// the two declarations are basically the same
// JVM will optimize this to StringBuilder
String test = "test";
test += "test";
StringBuilder test = new StringBuilder();
test.append("test");
On the other hand, if you don't do trivial concatenations, you will be better off with StringBuilder.
// this is worse, JVM won't be able to optimize
String test = "";
for(int i = 0; i < 100; i ++) {
test += "test";
}
// this is better
StringBuilder builder = new StringBuilder();
for(int i = 0; i < 100; i ++) {
builder.append("test");
}

Related

Joining string array together, from certain argument, into a string? [duplicate]

This question already has answers here:
What's the best way to build a string of delimited items in Java?
(37 answers)
Closed 6 years ago.
Here is my String array containing the following:
"message" "player" "how" "are" "you"
I am wanting to join the "how" "are" "you" part of the String[] and I am currently doing the following:
String msg = "";
for (int i = 2; i < args.length; i++)
{
msg = msg + args[i] + " ";
}
Util.messagePlayer(player, msg);
So my question is, is there a better/more efficient way of doing this?
Yes, there is a better way, everytime you are iterating that array, new String objects are getting created(because Strings are immutable), however this one is a short String, so the efficiency loss is not that considerable,still try to use StringBuilder instead
StringBuilder msg = new StringBuilder();
for (int i = 2; i < args.length; i++)
{
msg.append(args[i] + " ");
}
Util.messagePlayer(player, msg.toString);
For complete details, StringBuilder vs String concatenation in toString() in Java
String objects are immutable ones in Java, hence every time you concatenate two strings, you are creating a new Object this is costly.
Instead, you can use a StringBuilder.
More about how to use it is well described here:
Correct way to use StringBuilder

String builder vs string concatenation [duplicate]

This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 6 years ago.
What is the benefit and trade-off of using a string builder over pure string concatenation?
new StringBuilder(32).append(str1)
.append(" test: ")
.append(val)
.append(" is changed")
.toString();
vs say
str1 + " test: " + val + " is changed".
str1 is a random 10 character string.
str2 is a random 8 character string.
In your particular example, none because the compiler internally uses StringBuilders to do String concatenation. If the concatenation occurred in a loop, however, the compiler could create several StringBuilder and String objects. For example:
String s= "" ;
for(int i= 0 ; i < 10 ; i++ )
s+= "a" ;
Each time line 3 above is executed, a new StringBuilder object is created, the contents of s appended, "a" appended, and then the StringBuilder is converted into a String to be assigned back to s. A total of 10 StringBuilders and 10 Strings.
Conversely, in
StringBuilder sb= new StringBuilder() ;
for(int i= 0 ; i < 10 ; i++ )
sb.append( "a" );
String s= sb.toString() ;
Only 1 StringBuilder and 1 String are created.
The main reason for this is that the compiler could not be smart enough to understand that the first loop is equivalent to the second and generate more efficient (byte) code. In more complex cases, it's impossible even for the smartest compiler to know. If you absolutely need this optimization, you have to introduce it manually by using StringBuilders explicitly.
The quick answer is the performance:
when you are using native String classes it operates immutable strings, which means when you are writing
String line = "java";
String sufix = " is awesome";
line = line + sufix;
it will create two strings "java" and " is awesome", than create a new third string "java is awesome" from previous two ("java" and "is awesome") which later are likely to be deleted by a garbage collector (because they are no more used in app). That is a slow solution.
More faster solution is an appliance of StringBuffer class which through the smart algorightms that provide a buffer (that is obvious from its name) for merging strings and as a result would not remove the initial string during the concatenation process.
In case you are writing single thread-application (no concurrancy issues during which multiple threads access same object) it is better to apply StringBuilder which has even faster performance than the initial StringBuffer class.

How is + implemented in Java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
java String concatenation
Sources tell us that concat is implemented as follows:
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
Does + implementation differ when it comes to Strings? How? Is there a performance difference between + and concat. When should one be chosen over another?
This is a test I just made:
I created a class with those 3 instructions:
String s1 = "foo";
String s2 = "bar";
String s3 = s1 + s2;
Then I took the generated .class file and I decompiled using JAD decompiler.
This is how the code show up in the regenerated source:
String s = "foo";
String s1 = "bar";
String s2 = (new StringBuilder()).append(s).append(s1).toString();
So: this is the difference between + and concat.
I guess concat() is always better than StringBuilder, because it requires less objects to be created. You may chose StringBuilder if you want to append string repeatedly in a loop; in this case concat may create a new String each time, while StringBuilder may just expand the internal buffer. But, if StringBuilder is best in this last scenario, we can say that still concat() is better than +, in loops.

Why use append() instead of + [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why to use StringBuffer in Java instead of the string concatenation operator
what is the advantage or aim of doing this
int a= 42
StringBuffer sb = new StringBuffer(40);
String s = sb.append("a = ").append(a).append("!").toString();
System.out.println(sb);
result > a = 42!
instead of
int a= 42
String s = "a = " + a + "!";
System.out.println(sb);
In your scenario, I'm not sure there is a difference b/c all of your "+" are on one line (which only creates a String once). In general, though, Strings are immutable objects and are not truly manipulated but rather created and discarded using StringBuffers.
So ultimately, you will have more efficient code if you use StringBuffers (and generally StringBuilders). If you google "String vs. StringBuffer vs. StringBuilder" you can find many articles detailing the statistics.
Efficiency. String concatenation in Java uses StringBuilders in the background anyway, so in some cases you can eke out a bit of efficiency by controlling that yourself.
Just run the code for 10000 time and measure the time. It should be obvious.
Some background-information: String is immutable while StringBuilder is not. So everytime you concatenate a String you have to copy an array.
PS: Sometimes the compiler optimizes things though. Maybe if you make your variable static final it would be just one String internally and no concatenation.
First of all, StringBuffer is synchronized, so you would typically use StringBuilder. + has been reimplemented to use StringBuilder a while ago.
Second, as #Riggy mentioned Java actually does optimize + as long as they occur in a single expression. But if you were to do:
String s = "";
s += a;
s += b;
s += c;
s += d;
Then the effective code would become:
String s ="";
s = new StringBuilder(s).append(a).toString();
s = new StringBuilder(s).append(b).toString();
s = new StringBuilder(s).append(c).toString();
s = new StringBuilder(s).append(d).toString();
which is suboptimal to
String s = new StringBuilder(s).append(a).append(b).append(c).append(d).toString();
Because of compiler optimizations, it may or may not make any difference in your app. You'll have to run comparison speed tests to see.
But before you obsess about performance, get the program working right. "Premature optimization is the root of all evil."

Is there a way to build a Java String using an SLF4J-style formatting function?

I've heard that using StringBuilder is faster than using string concatenation, but I'm tired of wrestling with StringBuilder objects all of the time. I was recently exposed to the SLF4J logging library and I love the "just do the right thing" simplicity of its formatting when compared with String.format. Is there a library out there that would allow me to write something like:
int myInteger = 42;
MyObject myObject = new MyObject(); // Overrides toString()
String result = CoolFormatingLibrary.format("Simple way to format {} and {}",
myInteger, myObject);
Also, is there any reason (including performance but excluding fine-grained control of date and significant digit formatting) why I might want to use String.format over such a library if it does exist?
Although the Accepted answer is good, if (like me) one is interested in exactly Slf4J-style semantics, then the correct solution is to use Slf4J's MessageFormatter
Here is an example usage snippet:
public static String format(String format, Object... params) {
return MessageFormatter.arrayFormat(format, params).getMessage();
}
(Note that this example discards a last argument of type Throwable)
For concatenating strings one time, the old reliable "str" + param + "other str" is perfectly fine (it's actually converted by the compiler into a StringBuilder).
StringBuilders are mainly useful if you have to keep adding things to the string, but you can't get them all into one statement. For example, take a for loop:
String str = "";
for (int i = 0; i < 1000000; i++) {
str += i + " "; // ignoring the last-iteration problem
}
This will run much slower than the equivalent StringBuilder version:
StringBuilder sb = new StringBuilder(); // for extra speed, define the size
for (int i = 0; i < 1000000; i++) {
sb.append(i).append(" ");
}
String str = sb.toString();
But these two are functionally equivalent:
String str = var1 + " " + var2;
String str2 = new StringBuilder().append(var1).append(" ").append(var2).toString();
Having said all that, my actual answer is:
Check out java.text.MessageFormat. Sample code from the Javadocs:
int fileCount = 1273;
String diskName = "MyDisk";
Object[] testArgs = {new Long(fileCount), diskName};
MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0} file(s).");
System.out.println(form.format(testArgs));
Output:
The disk "MyDisk" contains 1,273 file(s).
There is also a static format method which does not require creating a MessageFormat object.
All such libraries will boil down to string concatenation at their most basic level, so there won't be much performance difference from one to another.
Plus it worth bearing in min that String.format() is a bad implementation of sprintf done with regexps, so if you profile your code you will see an patterns and int[] that you were not expecting.
MessageFormat and the slf MessageFormmater are generally faster and allocate less junk

Categories