StringBuilder buffer allocation support in compiler

Vitaly Davidovich vitalyd at gmail.com
Thu Jun 5 21:01:11 UTC 2014


I think your benchmark is testing something else though, which is cost of
resizing during appends.

To test the issue at hand, try writing two methods, one which does string
appends manually to a pre allocated SB of the right size (which is what you
want javac to do) and one that does the string concat.

Sent from my phone
On Jun 5, 2014 4:39 PM, "Laszlo Hornyak" <laszlo.hornyak at gmail.com> wrote:

> Hi Vitaly,
>
> I tested with server VM and the test code has some warmup so that the JIT
> should have enough time to kick in, but I will check stringopts if it
> should do some relevant optimization.
>
>
>
> On Thu, Jun 5, 2014 at 9:43 PM, Vitaly Davidovich <vitalyd at gmail.com>
> wrote:
>
>> Hi Laszlo,
>>
>> I believe server jit compiler has an optimization pass that will attempt
>> at fusing this type of pattern into one string allocation -- see
>> src/share/vm/opto/stringopts.[h|c]pp in the sources.  Have you tried
>> benchmarking this after jit compiler gets a crack at it?
>>
>>
>> On Thu, Jun 5, 2014 at 3:27 PM, Laszlo Hornyak <laszlo.hornyak at gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> Given this sample code
>>>
>>>     public static String sayHello(String name, int age) {
>>>         return "Hello " + name + ", this is your " + age + "th birthday";
>>>     }
>>>
>>> The compiler will generate this bytecode:
>>>        0: new           #11                 // class
>>> java/lang/StringBuilder
>>>        3: dup
>>>        4: invokespecial #12                 // Method
>>> java/lang/StringBuilder."<init>":()V
>>>        7: ldc           #19                 // String Hello
>>>        9: invokevirtual #15                 // Method
>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
>>>       12: aload_0
>>>       13: invokevirtual #15                 // Method
>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
>>>       16: ldc           #20                 // String , this is your
>>>       18: invokevirtual #15                 // Method
>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
>>>       21: iload_1
>>>       22: invokevirtual #13                 // Method
>>> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
>>>       25: ldc           #21                 // String th birthday
>>>       27: invokevirtual #15                 // Method
>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
>>>       30: invokevirtual #17                 // Method
>>> java/lang/StringBuilder.toString:()Ljava/lang/String;
>>>       33: areturn
>>>
>>> The most interesting line is:
>>>        4: invokespecial #12                 // Method
>>> java/lang/StringBuilder."<init>":()V
>>>
>>>
>>> Since all the string literals are given for the compiler, it could give
>>> an estimation on the required buffer size to the StringBuilder constructor.
>>> In this example the string literals already take 32 characters, plus a
>>> string representation of an integer takes up to 12 characters. The String
>>> size is 0 to Integer.MAX_VALUE, but 16 might be a good default. In this
>>> case a constructor call could be generated to allocate a buffer with 50
>>> characters and some (possibly all) buffer re-allocation could be saved in
>>> the subsequent append calls.
>>> The performance gain seems to be significant since the subsequent buffer
>>> allocations can take up to 30-40 percent of the execution time.
>>> Is there a specific reason for the java compiler not to support
>>> pre-allocation of StringBuilder buffer based on string literals and
>>> parameters?
>>>
>>> Thank you,
>>> Laszlo
>>>
>>>
>>> --
>>>
>>> EOF
>>>
>>
>>
>
>
> --
>
> EOF
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20140605/b61979d1/attachment-0001.html>


More information about the compiler-dev mailing list