Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: Re: Memory Use/Garbage Collection: Java vs Perl

by charnos (Friar)
on Sep 03, 2002 at 12:59 UTC ( [id://194747]=note: print w/replies, xml ) Need Help??


in reply to Re: Memory Use/Garbage Collection: Java vs Perl
in thread Memory Use/Garbage Collection: Java vs Perl

I originally was writing a question as to how throwing away string objects in Java was handled, and whether or not the 4 unused strings out of the 5 created were destroyed, but then I tripped over this line in the J2SE 1.4 API docs: "The Java language provides special support for the string concatentation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuffer class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java." I did some digging on java.sun.com, and that line is verbatim in every API dating back to JDK v1.1. So it appears as though a println() call using the + operator looks like this:
System.out.println(((new StringBuffer("I am'")).append(me.toString())) +.toString());
to the compiler (the last toString() because a PrintStream doesn't have a println() method that takes a StringBuffer). I was taught even in my first CS class (we learned Java) that strings worked the way you said, and I was under that assumption until about five minutes ago. Perhaps I am wrong, but in my reading of the docs it appears that Java handles string concatentation with the + operator as you suggested he try manually.

Replies are listed 'Best First'.
Re: Re: Re: Memory Use/Garbage Collection: Java vs Perl
by BrowserUk (Patriarch) on Sep 03, 2002 at 13:35 UTC

    You make a very good point! My bad on that bit.

    <excuses>

    I did say <cite>I think...</cite>

    What do you expect at a Perl site? Java expertise :8^)...

    </excuses>

    Being serious for a moment, if Javac is 'doing the right thing' on that line, that just means that it's memory overhead on recursive subroutines must be even worse than I thought. 4,000 -v- 2,000,000 recursions before blowing the stack is a mind-boggling 500 times less efficient in terms of memory/stack management. I guess I was looking for a rational explanation.

    Note: I have made no attempt to verify the numbers

    Update:I have confirmed that your assertion is true when using javac from jdk1.3.1 as follows

    import java.io.PrintStream; class dupme { public dupme(int i) { // 0 0:aload_0 // 1 1:invokespecial #1 <Method void Object()> // 2 4:getstatic #2 <Field PrintStream System.out> // 3 7:new #3 <Class StringBuffer> // 4 10:dup // 5 11:invokespecial #4 <Method void StringBuffer()> // 6 14:ldc1 #5 <String "I am '"> // 7 16:invokevirtual #6 <Method StringBuffer StringBuffe +r.append(String)> // 8 19:iload_1 // 9 20:invokevirtual #7 <Method StringBuffer StringBuffe +r.append(int)> // 10 23:ldc1 #8 <String "'!"> // 11 25:invokevirtual #6 <Method StringBuffer StringBuffe +r.append(String)> // 12 28:invokevirtual #9 <Method String StringBuffer.toSt +ring()> // 13 31:invokevirtual #10 <Method void PrintStream.println +(String)> // 14 34:new #11 <Class dupme> // 15 37:dup // 16 38:iload_1 // 17 39:iconst_1 // 18 40:iadd // 19 41:invokespecial #12 <Method void dupme(int)> // 20 44:astore_2 // 21 45:return } }

    Well It's better than the Abottoire, but Yorkshire!
      The Perl version needs to concatenate strings, too!
      perl -MO=Deparse,-q -e"print qq(I am $x\n)"
      produces
      print 'I am ' . $x . "\n";
      not print ('I am ' , $x , "\n" ).

      That is, Perl concatenates the literals and variables together into one string, then calls print with the result.

      —John

        That's interesting, thanks. Am I correct in my (I'm not sure if it's a memory of something I read somewhere, or an assumption I have formed) that Perl will fold string constants?

        From my (brief and un-expert) look at the byte code produced by javac, it seems to be pushing a new copy of the two constants onto the stack (they could be pointers to a single copy, I can't make up my mind) prior to the call to StringBuffer, at each invokation?

        Whereas I assume that Perl would push a reference to a single copy of each.

        Thinking about that, javac is probably pushing a pointer too.


        Well It's better than the Abottoire, but Yorkshire!
      this whole thread is pretty OT, so i won't let that stop me from pointing out...

      You aren't garunteed to get the behavior you are seeing from every implimentation of Java -- the JLS only requires that string concatination must be implimented using a StringBuffer, not that multiple string concatenations must be optimized into a single StringBuffer.

      ie...

      this... String foo = "bar" + "baz"; is garunteed to be equivilent to this... StringBuffer tmp = new StringBuffer("bar"); tmp.append("baz"); String foo = tmp.toString(); But this... String wb = "yakko" + "wakko" + "dot"; might be implimented as... StringBuffer tmp1 = new StringBuffer("yakko"); tmp1.append("wakko"); String tmp2 = tmp1.toString(); StringBuffer tmp3 = new StringBuffer(tmp2); tmp3.append("dot"); String wb = tmp3.toString();

      You might want to check out JDC TechTip 2002-03-05 particularly it's discussion of "a statement found in the Java Language Specification section 15.18.1.2"

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://194747]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2024-04-19 10:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found