java.net: Wiki

The Source for Java Technology Collaboration


 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (9 - 15 Aug 2008 - Main.club_lowlow)
Line: 1 to 1
 
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->

 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (8 - 28 Mar 2006 - Main.dubwai)
Line: 1 to 1
 
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 143 to 143
 -- Main.dubwai - 18 Jun 2003
Added:
>
>
UPDATE-

With the addition of the StringBuilder class in 1.5, the non-literal concatenation operation is now even faster. The performance increase comes from StringBuilder having no synchronization overhead. If you used String concatenation in the past, you will automatically get this boost when you compile in 1.5. StringBuilder is also a better choice for your legitimate Builder/Buffer needs in any case where thread synchronization is not a concern.

-- Main.dubwai - 28 Mar 2006

 
<-- anchor to allow a link to the discussion about this article -->

Discussion about AlwaysUseStringBufferMisconception
<-- generate a header for the discussion part of page -->

Deleted:
<
<

 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (7 - 23 Feb 2004 - Main.dubwai)
Line: 1 to 1
 
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 137 to 137
 for the StringBuffer version.
Changed:
<
<
If you look at these, you'll see that the only difference is that the StringBuffer version uses some extra instructions. Of course, as some people point out, there is no guarantee that the compiler will use StringBuffer for concatenation. This is true but in the case of concatenating two Strings both a non-StringBuffer concatenation and a StringBuffer concatenation require the creation of at least one more Object. In the case of the StringBuffer version, it's the StringBuffer itself. So you don't gain anything by using StringBuffer until you are concatenating at least three Strings if you gain anything at all. In reality, however, unless you are concatenating a large number of non-literal Strings the difference in performance is negligible. In practice, situations where are large number of non-literal Strings are concatenated outside of a loop are extremely rare. Using StringBuffer to concatenate a few normal sized non-literal Strings sacrifices readability for microscopic performance increases. 'Micro-optimizations' are generally considered bad practice and should be avoided.
>
>
If you look at these, you'll see that the only difference is that the StringBuffer version uses some extra instructions. Of course, as some people point out, there is no guarantee that the compiler will use StringBuffer for concatenation. This is true but in the case of concatenating two Strings both a non-StringBuffer concatenation and a StringBuffer concatenation require the creation of at least one more Object. In the case of the StringBuffer version, it's the StringBuffer itself. So you don't gain anything by using StringBuffer until you are concatenating at least three Strings if you gain anything at all. In reality, however, unless you are concatenating a large number of non-literal Strings the difference in performance is negligible. In practice, situations where are large number of non-literal Strings are concatenated outside of a loop are extremely rare. Using StringBuffer to concatenate a few normal sized non-literal Strings sacrifices readability for microscopic performance increases. 'Micro-optimizations' are generally considered bad practice and should be avoided. An exception to this rule is if you are concatenating to form a very large String (say thousands of characters) it can be beneficial to use a StringBuffer but only if you specify the initial size of the StringBuffer's underlying character array in the constructor. This saves the time required to 'resize' the char array (actually creating new arrays repeatedly.)
 In summary, using StringBuffers when concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is usually perfectly acceptable.

 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (6 - 27 Oct 2003 - Main.dubwai)
Line: 1 to 1
 
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 14 to 14
 
Added:
>
>
 for (int i = 0; i < 1000; i++) { s += i;
Line: 136 to 137
 for the StringBuffer version.
Changed:
<
<
If you look at these, you'll see that the only difference is that the StringBuffer version uses some extra instructions. Of course, as some people point out, there is no guarantee that the compiler will use StringBuffer for concatenation. This is true but in the case of concatenating two Strings both a non-StringBuffer concatenation and a StringBuffer concatenation require the creation of at least one more Object. In the case of the StringBuffer version, it's the StringBuffer itself. So you don't gain anything by using StringBuffer until you are concatenating at least three Strings if you gain anything at all. In reality, however, unless you are concatenating a large number of non-literal Strings the difference in performance is negligible. In practice, situations where are large number of non-literal Strings are concatenated outside of a loop are extremely rare. Using StringBuffer to concatenate a few non-literal Strings sacrifices readability for microscopic performance increases. 'Micro-optimizations' are generally considered bad practice and should be avoided.
>
>
If you look at these, you'll see that the only difference is that the StringBuffer version uses some extra instructions. Of course, as some people point out, there is no guarantee that the compiler will use StringBuffer for concatenation. This is true but in the case of concatenating two Strings both a non-StringBuffer concatenation and a StringBuffer concatenation require the creation of at least one more Object. In the case of the StringBuffer version, it's the StringBuffer itself. So you don't gain anything by using StringBuffer until you are concatenating at least three Strings if you gain anything at all. In reality, however, unless you are concatenating a large number of non-literal Strings the difference in performance is negligible. In practice, situations where are large number of non-literal Strings are concatenated outside of a loop are extremely rare. Using StringBuffer to concatenate a few normal sized non-literal Strings sacrifices readability for microscopic performance increases. 'Micro-optimizations' are generally considered bad practice and should be avoided.
 In summary, using StringBuffers when concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is usually perfectly acceptable.

 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (5 - 17 Sep 2003 - Main.dubwai)
Line: 1 to 1
 
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 138 to 138
 If you look at these, you'll see that the only difference is that the StringBuffer version uses some extra instructions. Of course, as some people point out, there is no guarantee that the compiler will use StringBuffer for concatenation. This is true but in the case of concatenating two Strings both a non-StringBuffer concatenation and a StringBuffer concatenation require the creation of at least one more Object. In the case of the StringBuffer version, it's the StringBuffer itself. So you don't gain anything by using StringBuffer until you are concatenating at least three Strings if you gain anything at all. In reality, however, unless you are concatenating a large number of non-literal Strings the difference in performance is negligible. In practice, situations where are large number of non-literal Strings are concatenated outside of a loop are extremely rare. Using StringBuffer to concatenate a few non-literal Strings sacrifices readability for microscopic performance increases. 'Micro-optimizations' are generally considered bad practice and should be avoided.
Changed:
<
<
In summary, using StringBuffers when concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is perfectly acceptable.
>
>
In summary, using StringBuffers when concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is usually perfectly acceptable.
 -- Main.dubwai - 18 Jun 2003

 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (4 - 23 Jun 2003 - Main.dubwai)
Line: 1 to 1
 
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 8 to 8
 

Origin of the Misconception

Changed:
<
<
Often, one of the first things an intermediate Java developer learns about is how String concatenation using the overloaded + operator is implemented. We learn that at runtime, a new Object must be created when the two Strings are put together. This can create a serious performance issue when done inside of a loop as follows:
>
>
Often, one of the things an intermediate Java developer discovers is how String concatenation using the overloaded + operator is implemented. We learn that at runtime, a new Object must be created when the two Strings are put together. This can create a serious performance issue when done inside of a loop as follows:
 
String s = "";
Line: 21 to 21
 What actually happens at runtime is that in every iteration of the loop, a new String is created and assigned to s. The solution is to use a StringBuffer to avoid creating a thousand new Objects.
Changed:
<
<
This is all true, however, you may be told that you should never use the overloaded + operator for Strings and that a StringBuffer should always be used to concatentate Strings. This is not true.
>
>
This is all true. You may be told, however, that you should never use the overloaded + operator for Strings and that a StringBuffer should always be used to concatentate Strings. This is not true.
 

Concatenating Literal Strings

Line: 67 to 67
  31 invokevirtual #10
Changed:
<
<
Without getting into what all these things mean, we can see one thing easily. The concatenation version is doing a lot less work. The reason is that the compiler will inline the concatenation of literal Strings. In other words, it 'realizes' that those Strings are not going to change, so it concatenates them at compile time. In the StringBuffer version, on the other hand, we have forced runtime concatenation and reduced the performance of the code. The more literal Strings we concatenate, the worse the StringBuffer solution performs relative to using the overloaded + operator.
>
>
Without getting into what all these things mean, we can see one thing easily. The concatenation version is doing a lot less work. The reason is that the compiler will inline the concatenation of literal Strings. In other words, it 'realizes' that those Strings are not going to change, so it concatenates them at compile time. In the StringBuffer version, on the other hand, we have forced runtime concatenation and actually degraded performance. The more literal Strings we concatenate, the worse the StringBuffer solution performs relative to using the overloaded + operator.
 

Concatenating Non-Literal Strings Outside of a Loop


 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (3 - 19 Jun 2003 - Main.leknor)
Line: 1 to 1
 
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->

AlwaysUseStringBufferMisconception
<-- this automatically adds a header showing the name of this page -->

Added:
>
>
 

Origin of the Misconception

Often, one of the first things an intermediate Java developer learns about is how String concatenation using the overloaded + operator is implemented. We learn that at runtime, a new Object must be created when the two Strings are put together. This can create a serious performance issue when done inside of a loop as follows:

Line: 136 to 138
 If you look at these, you'll see that the only difference is that the StringBuffer version uses some extra instructions. Of course, as some people point out, there is no guarantee that the compiler will use StringBuffer for concatenation. This is true but in the case of concatenating two Strings both a non-StringBuffer concatenation and a StringBuffer concatenation require the creation of at least one more Object. In the case of the StringBuffer version, it's the StringBuffer itself. So you don't gain anything by using StringBuffer until you are concatenating at least three Strings if you gain anything at all. In reality, however, unless you are concatenating a large number of non-literal Strings the difference in performance is negligible. In practice, situations where are large number of non-literal Strings are concatenated outside of a loop are extremely rare. Using StringBuffer to concatenate a few non-literal Strings sacrifices readability for microscopic performance increases. 'Micro-optimizations' are generally considered bad practice and should be avoided.
Changed:
<
<
In summary, using StringBuffers when concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is perfectly acceptable.
>
>
In summary, using StringBuffers when concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is perfectly acceptable.
 -- Main.dubwai - 18 Jun 2003

 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (2 - 18 Jun 2003 - Main.dubwai)
Line: 1 to 1
 
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 136 to 136
 If you look at these, you'll see that the only difference is that the StringBuffer version uses some extra instructions. Of course, as some people point out, there is no guarantee that the compiler will use StringBuffer for concatenation. This is true but in the case of concatenating two Strings both a non-StringBuffer concatenation and a StringBuffer concatenation require the creation of at least one more Object. In the case of the StringBuffer version, it's the StringBuffer itself. So you don't gain anything by using StringBuffer until you are concatenating at least three Strings if you gain anything at all. In reality, however, unless you are concatenating a large number of non-literal Strings the difference in performance is negligible. In practice, situations where are large number of non-literal Strings are concatenated outside of a loop are extremely rare. Using StringBuffer to concatenate a few non-literal Strings sacrifices readability for microscopic performance increases. 'Micro-optimizations' are generally considered bad practice and should be avoided.
Changed:
<
<
In summary, using StringBuffers when you are concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is perfectly acceptable.
>
>
In summary, using StringBuffers when concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is perfectly acceptable.
 -- Main.dubwai - 18 Jun 2003

 <<O>>  Difference Topic AlwaysUseStringBufferMisconception (1 - 18 Jun 2003 - Main.dubwai)
Line: 1 to 1
Added:
>
>
META TOPICPARENT name="Misconceptions"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->

AlwaysUseStringBufferMisconception
<-- this automatically adds a header showing the name of this page -->

Origin of the Misconception

Often, one of the first things an intermediate Java developer learns about is how String concatenation using the overloaded + operator is implemented. We learn that at runtime, a new Object must be created when the two Strings are put together. This can create a serious performance issue when done inside of a loop as follows:

String s = "";



for (int i = 0; i < 1000; i++)
{
    s += i;
}

What actually happens at runtime is that in every iteration of the loop, a new String is created and assigned to s. The solution is to use a StringBuffer to avoid creating a thousand new Objects.

This is all true, however, you may be told that you should never use the overloaded + operator for Strings and that a StringBuffer should always be used to concatentate Strings. This is not true.

Concatenating Literal Strings

Let's look at one form of String concatentation used in Java code: concatenating two or more literal Strings and it's StringBuffer analog.

String s = "This is the first line\n"
                +"This is the second line";

System.out.println(s);

StringBuffer b = new StringBuffer("This is the first line\n");
b.append("This is the second line");

System.out.println(b);

When compiled and run these both produce the same output. Using javap with the -c option, lets examine the bytecodes produced by the Sun 1.4.1_02-b6 compiler.

Here are the bytecodes for the concatenation version:

   0 ldc #2 <String "This is the first line
This is the second line">
   2 astore_1
   3 getstatic #3 <Field java.io.PrintStream out>
   6 aload_1
   7 invokevirtual #4 <Method void println(java.lang.String)>

And these are the bytecodes for the StringBuffer version:

  10 new #5 <Class java.lang.StringBuffer>
  13 dup
  14 ldc #6 <String "This is the first line
">
  16 invokespecial #7 <Method java.lang.StringBuffer(java.lang.String)>
  19 astore_2
  20 aload_2
  21 ldc #8 <String "This is the second line">
  23 invokevirtual #9 <Method java.lang.StringBuffer append(java.lang.String)>
  26 pop
  27 getstatic #3 <Field java.io.PrintStream out>
  30 aload_2
  31 invokevirtual #10 <Method void println(java.lang.Object)>

Without getting into what all these things mean, we can see one thing easily. The concatenation version is doing a lot less work. The reason is that the compiler will inline the concatenation of literal Strings. In other words, it 'realizes' that those Strings are not going to change, so it concatenates them at compile time. In the StringBuffer version, on the other hand, we have forced runtime concatenation and reduced the performance of the code. The more literal Strings we concatenate, the worse the StringBuffer solution performs relative to using the overloaded + operator.

Concatenating Non-Literal Strings Outside of a Loop

So what about non-literal concatenations? Let's look at another example.

String s1 = "this is the first line\n";
String s2 = "this is the second line";

s1 += s2;

and

String s1 = "this is the first line\n";
String s2 = "this is the second line";

StringBuffer b = new StringBuffer();
b.append(s1);
s1 = b.append(s2).toString();

And using javap we get:

   0 ldc #2 <String "this is the first line
">
   2 astore_1
   3 ldc #3 <String "this is the second line">
   5 astore_2
   6 new #4 <Class java.lang.StringBuffer>
   9 dup
  10 invokespecial #5 <Method java.lang.StringBuffer()>
  13 aload_1
  14 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
  17 aload_2
  18 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
  21 invokevirtual #7 <Method java.lang.String toString()>
  24 astore_1

For the concatenation version, and:

   0 ldc #2 <String "this is the first line
">
   2 astore_1
   3 ldc #3 <String "this is the second line">
   5 astore_2
   6 new #4 <Class java.lang.StringBuffer>
   9 dup
  10 invokespecial #5 <Method java.lang.StringBuffer()>
  13 astore_3
  14 aload_3
  15 aload_1
  16 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
  19 pop
  20 aload_3
  21 aload_2
  22 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
  25 invokevirtual #7 <Method java.lang.String toString()>
  28 astore_1

  29 return

for the StringBuffer version.

If you look at these, you'll see that the only difference is that the StringBuffer version uses some extra instructions. Of course, as some people point out, there is no guarantee that the compiler will use StringBuffer for concatenation. This is true but in the case of concatenating two Strings both a non-StringBuffer concatenation and a StringBuffer concatenation require the creation of at least one more Object. In the case of the StringBuffer version, it's the StringBuffer itself. So you don't gain anything by using StringBuffer until you are concatenating at least three Strings if you gain anything at all. In reality, however, unless you are concatenating a large number of non-literal Strings the difference in performance is negligible. In practice, situations where are large number of non-literal Strings are concatenated outside of a loop are extremely rare. Using StringBuffer to concatenate a few non-literal Strings sacrifices readability for microscopic performance increases. 'Micro-optimizations' are generally considered bad practice and should be avoided.

In summary, using StringBuffers when you are concatenating in a loop is good practice but otherwise, using the overloaded + operator with Strings is perfectly acceptable.

-- Main.dubwai - 18 Jun 2003

<-- anchor to allow a link to the discussion about this article -->

Discussion about AlwaysUseStringBufferMisconception
<-- generate a header for the discussion part of page -->


Topic AlwaysUseStringBufferMisconception . { View | Diffs r9 < r8 < r7 < r6 | More }
 XML java.net RSS