Concat an integer to a String - use String literal or primitive from performance and memory point of view?
Asked Answered
L

5

10

Option 1:

String newStr = someStr + 3 + "]";

Option 2:

String newStr = someStr + "3" + "]";

Which option is better with regards to performance, memory and general practice? What are some recommended tools/ways I can use to measure memory usage of my code and its performance (besides measuring the start time and the end time and calculate the difference)

Luetic answered 8/2, 2013 at 23:7 Comment(5)
Both doesnt make any difference.Battery
@Smit: Compiler will use a StringBuilder for String concatenationQuadruplicate
@Smit: using a StringBuilder would lead to the same byte-code as the code in the question, or worse.Gardening
@JBNizet and @ jlordo But this SO Answer saying something different. What I am understanding wrong? How Java do the string concatenation using “+”?Battery
Read the end of the answer, and the comments. The answer got it wrong first, and then tried to become correct. Read Mikhail Vladimirov's answer to this question.Gardening
P
11

The first will become:

StringBuilder sb = new StringBuilder (String.valueOf (someStr));
sb.append (3);
sb.append ("]");
String newStr = sb.toString ();

the second will become:

StringBuilder sb = new StringBuilder (String.valueOf (someStr));
sb.append ("3");
sb.append ("]");
String newStr = sb.toString ();

Here is disassembly:

public String foo (String someStr)
{
    String newStr = someStr + 3 + "]";
    return newStr;
}

public String bar (String someStr)
{
    String newStr = someStr + "3" + "]";
    return newStr;
}

public java.lang.String foo(java.lang.String);
Code:
   0: new           #16                 // class java/lang/StringBuilder
   3: dup
   4: aload_1
   5: invokestatic  #18                 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   8: invokespecial #24                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  11: iconst_3
  12: invokevirtual #27                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  15: ldc           #31                 // String ]
  17: invokevirtual #33                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  20: invokevirtual #36                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  23: astore_2
  24: aload_2
  25: areturn

public java.lang.String bar(java.lang.String);
Code:
   0: new           #16                 // class java/lang/StringBuilder
   3: dup
   4: aload_1
   5: invokestatic  #18                 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   8: invokespecial #24                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  11: ldc           #44                 // String 3
  13: invokevirtual #33                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  16: ldc           #31                 // String ]
  18: invokevirtual #33                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  21: invokevirtual #36                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  24: astore_2
  25: aload_2
  26: areturn
Pomfrey answered 8/2, 2013 at 23:13 Comment(4)
The first one will append 3 (boxed to Integer 3), then append ]. The second one appends 3]Raspberry
+1. I don't know why, but my eyes saw the constant in the second case, but not in the first one.Gardening
Oops. Steve Kuo is right. String s = "hello" + 3 + "]" creates a single String "hello3]" though. Strange that the compiler can't optimize this case. +1 still because I learnt something.Gardening
@JB Nizet: The compiler is required to optimize only for constant expressions. A method parameter is not constant.Trivet
G
7

There won't be any noticeable difference between both. Use what you find the most logical and readable. I would use

String newStr = someStr + "3]";
Gardening answered 8/2, 2013 at 23:11 Comment(0)
N
3

I would recommend Jprofiler as a great java application profiling tool that helped me find lots of memory problems.

I don't think option 1 and 2 have a big difference in terms of memory usage, especially if it is for a desktop application.

Neritic answered 8/2, 2013 at 23:12 Comment(0)
T
2

Assuming that someString is constant, both are constant expressions and will be evaluated at compile time. They will result in identical class files and runtime behavior.

Source: The Java Language Specification writes:

A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

  • Literals of primitive type and literals of type String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)

  • The additive operators + and - (§15.18)

  • ...

Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern.

If someString is not a constant, most modern compilers will use a StringBuilder, which is explicitly permitted by the Java Language Specification:

The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.

The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).

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.

Trivet answered 8/2, 2013 at 23:16 Comment(0)
P
0

Whenever you concatenate a string, on each concatenation, you create a new copy of the string and both strings are copied over, one character at a time. This results in a time complexity of O(n2) (McDowell).

If you want to improve performance, use

StringBuilder

One of its constructors has the following syntax:

public StringBuilder(int size); //Contains no character. Initial capacity of 'size'. 

StringBuilder (mutable sequence of characters. Remember strings are immmutable) helps resolve this problem by simply creating a resizable array of all the strings. copying them back to a string only when necessary (McDowell).

StringBuilder str = new StringBuilder(0);
str.append(someStr);
str.append(3);
str.append("]");

Reference:

McDowell, Gayle Laakmann. Cracking The Coding Interview, 6th Edition. Print.

"Stringbuilder (Java Platform SE 8 )". Docs.oracle.com. N.p., 2016. Web. 4 June 2016.

Postscript answered 4/6, 2016 at 15:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.