Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #7567 > unrolled thread

StringBuilder

Started bybob <bob@coolgroups.com>
First post2011-09-04 19:45 -0700
Last post2011-09-06 08:53 +0200
Articles 20 on this page of 36 — 10 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  StringBuilder bob <bob@coolgroups.com> - 2011-09-04 19:45 -0700
    Re: StringBuilder Arne Vajhøj <arne@vajhoej.dk> - 2011-09-04 22:53 -0400
    Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-05 05:27 +0200
      Re: StringBuilder Arne Vajhøj <arne@vajhoej.dk> - 2011-09-05 19:34 -0400
        Re: StringBuilder Wanja Gayk <brixomatic@yahoo.com> - 2011-09-11 16:35 +0200
          Re: StringBuilder Arne Vajhøj <arne@vajhoej.dk> - 2011-09-11 16:48 -0400
            Re: StringBuilder Wanja Gayk <brixomatic@yahoo.com> - 2011-09-17 02:54 +0200
              Re: StringBuilder Roedy Green <see_website@mindprod.com.invalid> - 2011-09-17 00:27 -0700
              Re: StringBuilder Lew <lewbloch@gmail.com> - 2011-09-18 01:42 -0700
                Re: StringBuilder Wanja Gayk <brixomatic@yahoo.com> - 2011-09-19 00:59 +0200
                  Re: StringBuilder Roedy Green <see_website@mindprod.com.invalid> - 2011-09-19 05:07 -0700
                    Re: StringBuilder Jeff Higgins <jeff@invalid.invalid> - 2011-09-19 11:38 -0400
      Re: StringBuilder Roedy Green <see_website@mindprod.com.invalid> - 2011-09-05 17:01 -0700
      Re: StringBuilder Stanimir Stamenkov <s7an10@netscape.net> - 2011-09-17 19:56 +0300
        Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-17 20:35 +0200
        Re: StringBuilder Roedy Green <see_website@mindprod.com.invalid> - 2011-09-17 15:34 -0700
          Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-18 01:33 +0200
            Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-18 01:56 +0200
            Re: StringBuilder Roedy Green <see_website@mindprod.com.invalid> - 2011-09-17 20:58 -0700
          Re: StringBuilder Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2011-09-17 22:44 -0700
            Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-18 09:54 +0200
              Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-18 09:59 +0200
              Re: StringBuilder Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2011-09-18 07:28 -0700
            Re: StringBuilder Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-09-18 08:15 -0400
              Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-18 15:32 +0200
                Re: StringBuilder Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-09-18 09:50 -0400
                  Re: StringBuilder Stanimir Stamenkov <s7an10@netscape.net> - 2011-09-18 17:08 +0300
                  Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-18 22:13 +0200
                    Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-18 22:29 +0200
                      Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-18 22:39 +0200
            Re: StringBuilder Roedy Green <see_website@mindprod.com.invalid> - 2011-09-19 09:45 -0700
    Re: StringBuilder Roedy Green <see_website@mindprod.com.invalid> - 2011-09-05 11:08 -0700
      Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-05 23:54 +0200
        Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-06 00:06 +0200
        Re: StringBuilder Roedy Green <see_website@mindprod.com.invalid> - 2011-09-05 17:03 -0700
          Re: StringBuilder Jan Burse <janburse@fastmail.fm> - 2011-09-06 08:53 +0200

Page 1 of 2  [1] 2  Next page →


#7567 — StringBuilder

Frombob <bob@coolgroups.com>
Date2011-09-04 19:45 -0700
SubjectStringBuilder
Message-ID<96f358c8-a024-40db-b60b-300186c2f813@o10g2000vby.googlegroups.com>
Is there any way to use StringBuilder but with + signs instead of
append?

[toc] | [next] | [standalone]


#7568

FromArne Vajhøj <arne@vajhoej.dk>
Date2011-09-04 22:53 -0400
Message-ID<4e6439aa$0$316$14726298@news.sunsite.dk>
In reply to#7567
On 9/4/2011 10:45 PM, bob wrote:
> Is there any way to use StringBuilder but with + signs instead of
> append?

Java does not support operator overload, so NO.

Arne

[toc] | [prev] | [next] | [standalone]


#7569

FromJan Burse <janburse@fastmail.fm>
Date2011-09-05 05:27 +0200
Message-ID<j41fik$3qb$1@news.albasani.net>
In reply to#7567
bob schrieb:
> Is there any way to use StringBuilder but with + signs instead of
> append?

The + in Java does already internally use StringBuilder.

There is only an issue when you want to accumulate a string
value. If you then explicitly use StringBuilder you are
faster, because you save the new StringBuilder() and toString().

So this is faster, since it uses 1 new and 1 toString():

     StringBuilder buf=new StringBuilder();
     for (int i=0; i<100; i++) {
        buf.append(i);
        buf("*");
        buf.append(i);
        buf.append("=");
        buf.append((i*i));
        buf.append("\n");
     }
     System.out.println(buf.toString());

Whereby this code is slower:

     String res="";
     for (int i=0; i<100; i++) {
        res+=i+"*"+i+"="+(i*i)+"\n";
     }
     System.out.println(res);

It is translated to the following code by the compiler, and
thus uses 100 new and 100 toString():

     String res="";
     for (int i=0; i<100; i++) {
         StringBuilder _buf=new StringBuilder(res);
         _buf.append(i);
         _buf("*");
         _buf.append(i);
         _buf.append("=");
         _buf.append((i*i));
         _buf.append("\n");
         res=_buf.toString();
     }
     System.out.println(res);

For more information see for example here:
http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/

Best Regards

[toc] | [prev] | [next] | [standalone]


#7591

FromArne Vajhøj <arne@vajhoej.dk>
Date2011-09-05 19:34 -0400
Message-ID<4e655caa$0$308$14726298@news.sunsite.dk>
In reply to#7569
On 9/4/2011 11:27 PM, Jan Burse wrote:
> bob schrieb:
>> Is there any way to use StringBuilder but with + signs instead of
>> append?
>
> The + in Java does already internally use StringBuilder.
>
> There is only an issue when you want to accumulate a string
> value. If you then explicitly use StringBuilder you are
> faster, because you save the new StringBuilder() and toString().
>
> So this is faster, since it uses 1 new and 1 toString():
>
> StringBuilder buf=new StringBuilder();
> for (int i=0; i<100; i++) {
> buf.append(i);
> buf("*");
> buf.append(i);
> buf.append("=");
> buf.append((i*i));
> buf.append("\n");
> }
> System.out.println(buf.toString());
>
> Whereby this code is slower:
>
> String res="";
> for (int i=0; i<100; i++) {
> res+=i+"*"+i+"="+(i*i)+"\n";
> }
> System.out.println(res);
>
> It is translated to the following code by the compiler, and
> thus uses 100 new and 100 toString():
>
> String res="";
> for (int i=0; i<100; i++) {
> StringBuilder _buf=new StringBuilder(res);
> _buf.append(i);
> _buf("*");
> _buf.append(i);
> _buf.append("=");
> _buf.append((i*i));
> _buf.append("\n");
> res=_buf.toString();
> }
> System.out.println(res);
>
> For more information see for example here:
> http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/

That has been known for 10-15 years.

It should be in any Java book above beginners level.

Arne

[toc] | [prev] | [next] | [standalone]


#7798

FromWanja Gayk <brixomatic@yahoo.com>
Date2011-09-11 16:35 +0200
Message-ID<MPG.28d6e5a3ee3006899896b2@202.177.16.121>
In reply to#7591
In article <4e655caa$0$308$14726298@news.sunsite.dk>, arne@vajhoej.dk 
says...
> > Whereby this code is slower:
> >
> > String res="";
> > for (int i=0; i<100; i++) {
> > res+=i+"*"+i+"="+(i*i)+"\n";
> > }
> > System.out.println(res);
> >
> > It is translated to the following code by the compiler, and
> > thus uses 100 new and 100 toString():
> >
> > String res="";
> > for (int i=0; i<100; i++) {
> > StringBuilder _buf=new StringBuilder(res);
> > _buf.append(i);
> > _buf("*");
> > _buf.append(i);
> > _buf.append("=");
> > _buf.append((i*i));
> > _buf.append("\n");
> > res=_buf.toString();
> > }
> > System.out.println(res);
> >
> > For more information see for example here:
> > http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/
> 
> That has been known for 10-15 years.
> 
> It should be in any Java book above beginners level.

Like other ancient performance-practices that have been obsoleted by 
today's compilers?

We have been told that using StringBuffer was the better alternative.
Now compilers have switched from using StringBuffer for the above 
example to the unsynchronized StringBuilder. Those who have manually 
used the StringBuffer have stopped the compiler for doing that for them 
and must rely on the JITs lock elision algorithm.

So as long as this part of the code does not represent a critical 
performance-bottleneck, I would recommend to use the simple, stupid 
"slow" variant and hope for future compilers to detect and optimize that 
pattern.

> http://java.sun.com/developer/technicalArticles/Interviews/community/k
abutz_qa.html <

Kind regards,
Wanja



-- 
..Alesi's problem was that the back of the car was jumping up and down 
dangerously - and I can assure you from having been teammate to 
Jean Alesi and knowing what kind of cars that he can pull up with, 
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---

[toc] | [prev] | [next] | [standalone]


#7818

FromArne Vajhøj <arne@vajhoej.dk>
Date2011-09-11 16:48 -0400
Message-ID<4e6d1eb6$0$306$14726298@news.sunsite.dk>
In reply to#7798
On 9/11/2011 10:35 AM, Wanja Gayk wrote:
> In article<4e655caa$0$308$14726298@news.sunsite.dk>, arne@vajhoej.dk
> says...
>>> Whereby this code is slower:
>>>
>>> String res="";
>>> for (int i=0; i<100; i++) {
>>> res+=i+"*"+i+"="+(i*i)+"\n";
>>> }
>>> System.out.println(res);
>>>
>>> It is translated to the following code by the compiler, and
>>> thus uses 100 new and 100 toString():
>>>
>>> String res="";
>>> for (int i=0; i<100; i++) {
>>> StringBuilder _buf=new StringBuilder(res);
>>> _buf.append(i);
>>> _buf("*");
>>> _buf.append(i);
>>> _buf.append("=");
>>> _buf.append((i*i));
>>> _buf.append("\n");
>>> res=_buf.toString();
>>> }
>>> System.out.println(res);
>>>
>>> For more information see for example here:
>>> http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/
>>
>> That has been known for 10-15 years.
>>
>> It should be in any Java book above beginners level.
>
> Like other ancient performance-practices that have been obsoleted by
> today's compilers?

No.

What we are talking about is the "+=" part and that part is
still relevant for todays compilers.

Actually JB's example use = but to be equivalent to the first code
the it need to be +=.

And besides what he mention as reasons there are also
the 100 new strings.

> We have been told that using StringBuffer was the better alternative.
> Now compilers have switched from using StringBuffer for the above
> example to the unsynchronized StringBuilder. Those who have manually
> used the StringBuffer have stopped the compiler for doing that for them
> and must rely on the JITs lock elision algorithm.

That is a little interesting quirk.

The outside loop string += part is more efficient with StringB*. And
I am pretty sure that the StringBuffer/StringBuilder difference
is negligible.

But the inside loop string + is probably a little bit faster
with StringBuilder than StringBuffer.

You can consider that insignificant compared to the first.

Or you could argue for using StringB* and append of string +.

> So as long as this part of the code does not represent a critical
> performance-bottleneck, I would recommend to use the simple, stupid
> "slow" variant and hope for future compilers to detect and optimize that
> pattern.

As long as it is not critical then readability should be the deciding
factor.

Arne

[toc] | [prev] | [next] | [standalone]


#8097

FromWanja Gayk <brixomatic@yahoo.com>
Date2011-09-17 02:54 +0200
Message-ID<MPG.28de0e1952218cb9896be@202.177.16.121>
In reply to#7818
In article <4e6d1eb6$0$306$14726298@news.sunsite.dk>, arne@vajhoej.dk 
says...

> >> It should be in any Java book above beginners level.
> >
> > Like other ancient performance-practices that have been obsoleted by
> > today's compilers?
> 
> No.
> 
> What we are talking about is the "+=" part and that part is
> still relevant for todays compilers.

And "still" is the keyword. The question remains: For how long will this 
hold true?

> Actually JB's example use = but to be equivalent to the first code
> the it need to be +=.
> 
> And besides what he mention as reasons there are also
> the 100 new strings.

So what's the problem with these? before answering, just have a look at 
this: 
http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html

> > We have been told that using StringBuffer was the better alternative.
> > Now compilers have switched from using StringBuffer for the above
> > example to the unsynchronized StringBuilder. Those who have manually
> > used the StringBuffer have stopped the compiler for doing that for them
> > and must rely on the JITs lock elision algorithm.
> 
> That is a little interesting quirk.
> 
> The outside loop string += part is more efficient with StringB*. And
> I am pretty sure that the StringBuffer/StringBuilder difference
> is negligible.
> 
> But the inside loop string + is probably a little bit faster
> with StringBuilder than StringBuffer.
> 
> You can consider that insignificant compared to the first.
> 
> Or you could argue for using StringB* and append of string +.

Nope, I'm arguing that:

String x="";
for(String s : strings){
 x+=s;
}

or 

String x="";
for(String s : strings){
 x=x+s;
}

Is simple pattern that could be detected by tomorrows JIT-compilers and 
transformed into:

StringBuilder b = new StringBuilder();
for(String s : strings){
 b.append(s);
}
String x = b.toString();

But I don't think any compiler programmer would care to detect this 
pattern:

StringBuffer b = new StringBuffer ();
for(String s : strings){
 b.append(s);
}
String x = b.toString();

Just to transform it into the the StringBuilder-variant.

> > So as long as this part of the code does not represent a critical
> > performance-bottleneck, I would recommend to use the simple, stupid
> > "slow" variant and hope for future compilers to detect and optimize that
> > pattern.
> 
> As long as it is not critical then readability should be the deciding
> factor.

That's exactly what I'm saying.

Kind regards,
Wanja


-- 
..Alesi's problem was that the back of the car was jumping up and down 
dangerously - and I can assure you from having been teammate to 
Jean Alesi and knowing what kind of cars that he can pull up with, 
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---

[toc] | [prev] | [next] | [standalone]


#8102

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-09-17 00:27 -0700
Message-ID<5ri87757ieatesdngnpol1c7qqb568d24e@4ax.com>
In reply to#8097
On Sat, 17 Sep 2011 02:54:28 +0200, Wanja Gayk <brixomatic@yahoo.com>
wrote, quoted or indirectly quoted someone who said :

>
>Is simple pattern that could be detected by tomorrows JIT-compilers and 
>transformed into:

I jittered at the Jet people about such optimisations.  They seemed to
feel that string concatenation was not important an operation for
people to worry about in optimising.  I disagreed since so much of my
code is about fiddling text. I don't have a handle on its importance
generally.
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
Your top priority should be fixing bugs. If you carry on development, 
you are just creating more places you will have to search for them.

[toc] | [prev] | [next] | [standalone]


#8120

FromLew <lewbloch@gmail.com>
Date2011-09-18 01:42 -0700
Message-ID<15369681.1051.1316335323980.JavaMail.geo-discussion-forums@prfh23>
In reply to#8097
Wanja Gayk wrote:
> ar...@vajhoej.dk says...
> 
>>>> It should be in any Java book above beginners level.
>>>
>>> Like other ancient performance-practices that have been obsoleted by
>>> today's compilers?
>> 
>> No.
>> 
>> What we are talking about is the "+=" part and that part is
>> still relevant for todays compilers.
> 
> And "still" is the keyword. The question remains: For how long will this 
> hold true?

You said "today's compilers".

>> Actually JB's example use = but to be equivalent to the first code
>> the it need to be +=.
>> 
>> And besides what he mention as reasons there are also
>> the 100 new strings.
> 
> So what's the problem with these? before answering, just have a look at 
> this: 
> http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html

That tells part of the story, but extra objects still cause both memory and time overhead.  Time comes from GC cycles that kick in because you were profligate.
...[snip] ...
> 
> Nope, I'm arguing that:
> 
> String x="";
> for(String s : strings){
>  x+=s;
> }
> 
> or 
> 
> String x="";
> for(String s : strings){
>  x=x+s;
> }
> 
> Is simple pattern that could be detected by tomorrows JIT-compilers and 

But you changed your argument.  You _were_ speaking of "today's compilers".  Now suddenly you're speaking of "tomorrows [sic] JIT-compilers".

Besides shifting your ground, you have weakened your argument.  It's one thing to program to allow "tomorrow's compilers" to further optimize your code, it's quite another to program to *require* "tomorrow's compilers" to further optimize your code.

You don't know for a fact that "tomorrow's compilers" will ever optimize across multiple lines of 'String' concatenation.

As you say, they "could be" able to do that; you just cannot aver that they will be able to do that.

But of course, that's only now that you've moved the discussion from "today's compilers" as you first said, to "tomorrow's compilers" as you now wish to discuss.

> transformed into:
> 
> StringBuilder b = new StringBuilder();
> for(String s : strings){
>  b.append(s);
> }
> String x = b.toString();
> 
> But I don't think any compiler programmer would care to detect this 
> pattern:
> 
> StringBuffer b = new StringBuffer ();
> for(String s : strings){
>  b.append(s);
> }
> String x = b.toString();
> 
> Just to transform it into the the StringBuilder-variant.

That would likely be incorrect anyway, since the semantics differ.  Of course, "tomorrow's JIT compiler" could figure out that there's no thread leak, so it "could be" able to do it.  Maybe.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#8146

FromWanja Gayk <brixomatic@yahoo.com>
Date2011-09-19 00:59 +0200
Message-ID<MPG.28e09640efac3e899896c2@202.177.16.121>
In reply to#8120
In article <15369681.1051.1316335323980.JavaMail.geo-discussion-
forums@prfh23>, lewbloch@gmail.com says...

> >>>> It should be in any Java book above beginners level.
> >>>
> >>> Like other ancient performance-practices that have been obsoleted by
> >>> today's compilers?
> >> 
> >> No.
> >> 
> >> What we are talking about is the "+=" part and that part is
> >> still relevant for todays compilers.
> > 
> > And "still" is the keyword. The question remains: For how long will this 
> > hold true?
> 
> You said "today's compilers".

Referring to other, nowadays old performance-practices.

> >> And besides what he mention as reasons there are also
> >> the 100 new strings.
> > 
> > So what's the problem with these? before answering, just have a look at 
> > this: 
> > http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html
> 
> That tells part of the story, but extra objects still cause both memory and time overhead.  Time comes from GC cycles that kick in because you were profligate.
> ...[snip] ...

Still, If i had to chose whether to trust Brian Goetz' opinion on this 
topic or yours, I'm sorry, I'd chose Brian's. I'd prefer to have these 
objects discarded in a minor collection than in a major "stop the 
world" collection.

> > Nope, I'm arguing that:
> > 
> > String x="";
> > for(String s : strings){
> >  x+=s;
> > }
> > 
> > or 
> > 
> > String x="";
> > for(String s : strings){
> >  x=x+s;
> > }
> > 
> > Is simple pattern that could be detected by tomorrows JIT-compilers and 
> 
> But you changed your argument.  You _were_ speaking of "today's compilers".  Now suddenly you're speaking of "tomorrows [sic] JIT-compilers".

I wasn't.
What I was saying was that (maybe my english is not good enough our you 
deliberately want to misunderstand me, just to "win a discussion") there 
have been numerous performance-advices which have been obsoletey by 
today's compilers and that I expect this one to be an advice that will 
be obsoleted by tomorrow's compilers. I hope I'm being clear now - even 
though I think that it was clear enough from the beginning.

> Besides shifting your ground, you have weakened your argument.  It's one thing to program to allow "tomorrow's compilers" to further optimize your code, it's quite another to program to *require* "tomorrow's compilers" to further optimize your code.

Let me put it this way: I would not advice someone to use any 
performance tweak by default, but to use the dumb, readable version 
instead and optimize only if it really matters.

Kind regards,
Wanja

-- 
..Alesi's problem was that the back of the car was jumping up and down 
dangerously - and I can assure you from having been teammate to 
Jean Alesi and knowing what kind of cars that he can pull up with, 
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---

[toc] | [prev] | [next] | [standalone]


#8152

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-09-19 05:07 -0700
Message-ID<jvbe77h1f0gds5fpa83lvojghp9d542tkg@4ax.com>
In reply to#8146
On Mon, 19 Sep 2011 00:59:59 +0200, Wanja Gayk <brixomatic@yahoo.com>
wrote, quoted or indirectly quoted someone who said :

>I wasn't.
>What I was saying was that (maybe my english is not good enough our you 
>deliberately want to misunderstand me, just to "win a discussion")

Lew really wanted to be a prosecution lawyer.  It is good practice
talking to him. He forces you to use precisely correct and unambiguous
language. However I admit he takes an unusually savage glee in
humiliating ESL students. Maybe his wife beats him.

-- 
Roedy Green Canadian Mind Products
http://mindprod.com
It is a lot easier to combine things later that 
have been too finely categorised than to split 
things later whose are categories are too coarse.

[toc] | [prev] | [next] | [standalone]


#8153

FromJeff Higgins <jeff@invalid.invalid>
Date2011-09-19 11:38 -0400
Message-ID<j57nd9$cti$1@dont-email.me>
In reply to#8152
On 09/19/2011 08:07 AM, Roedy Green wrote:
> On Mon, 19 Sep 2011 00:59:59 +0200, Wanja Gayk<brixomatic@yahoo.com>
> wrote, quoted or indirectly quoted someone who said :
>
>> I wasn't.
>> What I was saying was that (maybe my english is not good enough our you
>> deliberately want to misunderstand me, just to "win a discussion")

Read it and weep.
<http://en.wikipedia.org/wiki/English_orthography>

> Lew really wanted to be a prosecution lawyer.  It is good practice
> talking to him. He forces you to use precisely correct and unambiguous
> language. However I admit he takes an unusually savage glee in
> humiliating ESL students. Maybe his wife beats him.
>

[toc] | [prev] | [next] | [standalone]


#7595

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-09-05 17:01 -0700
Message-ID<sjoa675nor2ns2o0ulbg0l7t76k094u1mn@4ax.com>
In reply to#7569
On Mon, 05 Sep 2011 05:27:15 +0200, Jan Burse <janburse@fastmail.fm>
wrote, quoted or indirectly quoted someone who said :

>
>So this is faster, since it uses 1 new and 1 toString():

Further you can optimise the size of the buffer.  In experiments I did
with a program that does a lot of String building this improved
performance by 10%

I now use FastCat which gets the size of the buffer bang on every
time.

see http://mindprod.com/products1.html#FASTCAT
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
The modern conservative is engaged in one of man's oldest exercises in moral philosophy; that is, 
the search for a superior moral justification for selfishness.
~ John Kenneth Galbraith (born: 1908-10-15 died: 2006-04-29 at age: 97) 

[toc] | [prev] | [next] | [standalone]


#8107

FromStanimir Stamenkov <s7an10@netscape.net>
Date2011-09-17 19:56 +0300
Message-ID<j52jgd$iij$1@dont-email.me>
In reply to#7569
Mon, 05 Sep 2011 05:27:15 +0200, /Jan Burse/:

> If you then explicitly use StringBuilder you are
> faster, because you save the new StringBuilder() and toString().
>
> So this is faster, since it uses 1 new and 1 toString():

The StringBuilder.toString() is really fast - that's the point, and 
I don't think it is worth mentioning it.

-- 
Stanimir

[toc] | [prev] | [next] | [standalone]


#8108

FromJan Burse <janburse@fastmail.fm>
Date2011-09-17 20:35 +0200
Message-ID<j52pa6$ptl$1@news.albasani.net>
In reply to#8107
Stanimir Stamenkov schrieb:
> Mon, 05 Sep 2011 05:27:15 +0200, /Jan Burse/:
>
>> If you then explicitly use StringBuilder you are
>> faster, because you save the new StringBuilder() and toString().
>>
>> So this is faster, since it uses 1 new and 1 toString():
>
> The StringBuilder.toString() is really fast - that's the point, and I
> don't think it is worth mentioning it.
>

I am not sure whether I can agree directly.

The StringBuilder is a mutable object. The String is a
immutable object. Therefore the obvious fast implementation
that would share the buffer between StringBuilder and
String does not work. Because the following code would
break the immutability of String:

    StringBuilder buf=new StringBuilder();

    buf.append("Hello World!");

    String str=buf.toString();

    buf.replace(6,11,"Java");

    System.out.println("str="+str);

By a side effect via buf replace the value of the
string str would change. Therefore we find the following
slow implementation of toString() in the reference
implementation. Please note the comment:

429     public String toString() {
430         // Create a copy, don't share the array
431         return new String(value, 0, count);
432     }

http://kickjava.com/src/java/lang/StringBuilder.java.htm

And if we look at the used constructor, it does really
make a copy. There would be a non public constructor
in String that allows some sharing, and that is for
example used to implement substring. But this time
a constructor is used that does not do a sharing:

197     public String(char value[], int offset, int count) {
198         if (offset < 0) {
199             throw new StringIndexOutOfBoundsException(offset);
200         }
201         if (count < 0) {
202             throw new StringIndexOutOfBoundsException(count);
203         }
204         // Note: offset or count might be near -1>>>1.
205         if (offset > value.length - count) {
206             throw new StringIndexOutOfBoundsException
                               (offset + count);
207         }
208         char[] v = new char[count];
209         System.arraycopy(value, offset, v, 0, count);
210         this.offset = 0;
211         this.count = count;
212         this.value = v;
213     }

http://kickjava.com/src/java/lang/String.java.htm

Eventually some programm analysis would allow sharing.
But the copying has also a positive effect. When
the StringBuilder by manipulation has gained a much
greater capacity than necessary, then the copying will
create a smaller char array, so that less space is used
as soon as the StringBuilder is reclaimed.

But maybe you are right, that toString() is nevertheless
fast. Since a) allocating objects is usually fast and
b) System array copy can also be fast. And together
with the capacity reducing effect this could all lead
to a small overhead.

BTW: OpenJDK uses the same code. In Harmony we find
a shared flag in the AbstractStringBuilder, and a
heuristic when sharing is done or not. The non public
String constructor is used for sharing:

    public String toString() {
        if (count == 0) {
            return ""; //$NON-NLS-1$
        }
        // Optimize String sharing for more performance
        int wasted = value.length - count;
        if (wasted >= 256
                || (wasted >= INITIAL_CAPACITY &&
                             wasted >= (count >> 1))) {
                     return new String(value, 0, count);
        }
        shared = true;
        return new String(0, count, value);
    }

http://www.java2s.com/Open-Source/Java-Document/Apache-Harmony-Java-SE/java-package/java/lang/AbstractStringBuilder.java.htm

There is then a little overhead in the basic operations
of StringBuilder to check for sharing, and in case that
there is sharing, a copy is made.

    final void replace0(int start, int end, String string) {
      [...]
      if (!shared) {
          // index == count case is no-op
          System.arraycopy(value, end, value, start
                   + stringLength, count - end);
      } else {
          char[] newData = new char[value.length];
          System.arraycopy(value, 0, newData, 0, start);
          // index == count case is no-op
          System.arraycopy(value, end, newData, start
                   + stringLength, count - end);
          value = newData;
          shared = false;
      }

Probably gain in speed by the sharing compensates for
this little extra check needed everwhere. So probably
toString() is relatively fast here, assuming that sharing
happens enough often. When we look at the loop example
then we can positively influence sharing when we give
a good initial capacity, because then waste is small.

But giving an initial capacity for the whole loop is
propably non trivial. How does the digit size of
squares develop. So assume our StringBuilder grows
according to its enlargeBuffer rule. In the case of
Harmony the capacity is growing by a factor 1.5 and by
adding 2.

So initially we will have waste >= count/2 whenever
an enlargement happend, because of the adding of two
we have waste = count/2 + 2. So no sharing will happen.
When we then have added n characters, we will have
waste' = count/2 + 2 - n and count' = count + n.
We have only waste' < count' / 2 when 2 - n < n / 2.
So only after adding 2 characters sharing will happen
again for shure.

So the heuristic has a little glitch. But never mind.

Best Regards

[toc] | [prev] | [next] | [standalone]


#8110

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-09-17 15:34 -0700
Message-ID<vp7a77lp3e5oe4h79pnmv95vb4lu13spmc@4ax.com>
In reply to#8107
On Sat, 17 Sep 2011 19:56:50 +0300, Stanimir Stamenkov
<s7an10@netscape.net> wrote, quoted or indirectly quoted someone who
said :

>The StringBuilder.toString() is really fast - that's the point, and 
>I don't think it is worth mentioning it.

The places where StringBuilder wastes CPU cycles is when you have a
bad estimate and it has to create new buffer and copy what it has done
so far to it. If estimate is two low, you can get repeated such
doublings.  If it is too high, you fill up RAM too quickly and force
premature c.

My solution was FastCat which is quite easy to get a bang on estimate.
see http://mindprod.com/products1.html#FASTCAT

StringBuilder composes its string in a char[].  Unfortunately it can't
simply plop that into a String object at the end.  It has to allocate
yet another buffer, copy into it, and that becomes your string object.
The JVM is worried there might be encumbrances (pointers to) the
char[].  So it has to copy rather than reference.  Perhaps a little
native code could bypass the final copy.
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
Your top priority should be fixing bugs. If you carry on development, 
you are just creating more places you will have to search for them.

[toc] | [prev] | [next] | [standalone]


#8111

FromJan Burse <janburse@fastmail.fm>
Date2011-09-18 01:33 +0200
Message-ID<j53aom$m0$1@news.albasani.net>
In reply to#8110
Roedy Green schrieb:
> The JVM is worried there might be encumbrances (pointers to) the char[].

Well, strictly speaking, a pointer alone is not harmful and quite
impossible since the field is for example package local in the
AbstractStringBuilder class and the accessor is also package local.

The problem is invoking a method of an object that has access to
the char[] and will do some write into the array between offset
and offset+count of the string.

Bye

[toc] | [prev] | [next] | [standalone]


#8113

FromJan Burse <janburse@fastmail.fm>
Date2011-09-18 01:56 +0200
Message-ID<j53c2o$32e$1@news.albasani.net>
In reply to#8111
Jan Burse schrieb:
> quite impossible

Well not impossible. Via reflection we can access it
even when it is package local:

http://download.oracle.com/javase/6/docs/api/java/lang/reflect/AccessibleObject.html

Hm ...

[toc] | [prev] | [next] | [standalone]


#8115

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-09-17 20:58 -0700
Message-ID<k2ra771tvpctof9v094t36ldo1g7escv3d@4ax.com>
In reply to#8111
On Sun, 18 Sep 2011 01:33:41 +0200, Jan Burse <janburse@fastmail.fm>
wrote, quoted or indirectly quoted someone who said :

>The problem is invoking a method of an object that has access to
>the char[] and will do some write into the array between offset
>and offset+count of the string.

Exactly.  If there exists a reference to the char after it is inside
the String, that is a security breach, since it could be used to
modify the String.
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
Your top priority should be fixing bugs. If you carry on development, 
you are just creating more places you will have to search for them.

[toc] | [prev] | [next] | [standalone]


#8116

FromPeter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com>
Date2011-09-17 22:44 -0700
Message-ID<GeednbWNqODBGOjTnZ2dnUVZ_rqdnZ2d@posted.palinacquisition>
In reply to#8110
On 9/17/11 3:34 PM, Roedy Green wrote:
> [...]
> StringBuilder composes its string in a char[].  Unfortunately it can't
> simply plop that into a String object at the end.  It has to allocate
> yet another buffer, copy into it, and that becomes your string object. [...]

Are you sure that's the implementation?

In .NET, there is also a String and StringBuilder class pair, and 
StringBuilder.ToString() does in fact just create a new String instance 
using the existing buffer.  It flags itself that it did so, and of 
course then it does have to allocate a new buffer if you mutate the 
StringBuilder instance later.  But the most common scenario is to mutate 
the StringBuilder, then get the String instance just once, discarding 
the StringBuilder immediately after.

I don't really care that much so I'm not going to waste time checking 
myself.  But if anyone does think it's something to worry about, they 
should at least check the actual implementation to make sure it really 
does what they think it does.

In any case, if Java does _not_ implement it that way, I suspect that's 
out of a different decision-making process rather than ignorance.  In 
other words, they have already considered whether it's a worthwhile 
optimization and decided otherwise.  Which strongly suggests that anyone 
worrying a priori about the performance of StringBuilder before they 
have demonstrated it's an actual bottleneck in their program is wasting 
their time.

Pete

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web