String.valueOf(String string)



  • We all know Java provides very convenient way of joining Strings - you only have to write is:



    int foo = foo();

    System.out.println("The value of foo is: " + foo);



    to receive the expected result. Fewer people
    know that additional temporary garbage-collectable StringBuffer object is created,
    therefore the last line actually expands to:



    System.out.println(new StringBuffer("The value of foo is: ").append(foo).toString());


    This is just fine. But now if you think that:



    System.out.println(foo + " is the value of foo.");



    will expand to:


    System.out.println(new StringBuffer().append(foo).append(" is the value of foo.").toString());



    you are wrong. Looking into the bytecode created by Sun compilers you will find out that it actually expands to:


    System.out.println(new StringBuffer(String.valueOf(foo)).append(" is the value of foo.").toString());



    That means two additional temporary garbage-collectable objects are created. This
    is inefficient, but not yet wtf. The real wtf is that String.valueOf is
    called even for non-literal String objects - last line in:



    String message = "The value of foo is: ";

    System.out.println(message + foo);



    will expand to:


    System.out.println(new StringBuffer(String.valueOf(message)).append(foo).toString());



    !!! (look for String.valueOf(java.lang.Object) import appearing in the
    class file). And all of this is instead of message.concat(foo) that creates no additional objects at al.



    There's a caveat here that String.valueOf will also work
    for null values (producing "null"), but did it really worth two
    function calls with one of them (String.toString()) virtual? At least
    they could define String.valueOf(String string) returning simply it's
    argument when non-null.




  • There's probably a very good reason for doing it this way that is not obvious to us mere mortals.

    Personally, and no offence meant, I trust the people at Sun to know better than you.



  • Then you obviously don't know how much Java has changed since inception
    and how many bugs and limitations are already fixed. And how many are
    still open, and how many bugs cannot be fixed without breaking backward
    compatibility. But it's your right to believe in any gods you want,
    especially if you don't do any real development. (No offence meant. :))



  • Java sucks



  •   I must concur, java sucks - its an anal retentive

    "language" and its entire garbage collection

    "feature" is inefficient and promotes laziness and lack

    of responsibility for the chickenshit programmers that

    use the language ;)>  So, the real WTF here is the

    existence of java and the corollary WTF is the

    consequent existence of  java programmers...



    Dr MindHacker

    Open Source Developer



  • @firewireguy said:

    There's probably a very good reason for doing it this way that is not obvious to us mere mortals.

    Personally, and no offence meant, I trust the people at Sun to know better than you.

    I don't, for the same reason that Savior gave and that DrMindHacker concurred -- Java sucks.

    That's not to say that it couldn't be better.... Microsoft actually did a good thing when they took Java, put it in a bag, shook it up, put it in an oven, and pulled out C# and the .NET framework. All the pros of Java -- bytecode, garbage collection (which *is* a good thing, DrMindHacker), platform independance, etc. -- but without the poor implementation that Sun came up with.

    To continue on topic... I agree, huge WTF. One huge problem I have with Sun's Java implementation is their over-use of StringBuilders... like for simple concatenation. In your simple examples, meratcolumn1, the use of the StringBuilder is *less* performant than the use of a simple string concatenation. It's only after several large concatenations that a StringBuilder should be used, and the Java compiler should be able to figure that out.



  • Real programmer should program with ease everything designed to be
    programmed, and with some troubles - anything never thought of being
    programmed. Limiting self to predictable and controllable
    environments like C is for weak minds.



  • heh.... "C" is predictable and controllable....

     

    you obviously haven't seen some of the C code that I have. Someday I may have to email some of it to Alex. ;)



  • And C# and .NET are certainly platform independant -- er -- independent.



    Any platform you want, so long as it's Windows.



    They said the same thing about VFP3 -- platform independent. Windows
    '95, '98, NT4, etc. -- any version of Windows that you want.



    There's flexibility for you.



  • @ohng69 said:

    And C# and .NET are certainly platform independant -- er -- independent.



    Any platform you want, so long as it's Windows.




    Mono? Portable.net?



  • No offense dude, but exactly what is the point? If you hate the inefficiencies of Java (which I understand there are many), then your options are:

    A) Get a job at Sun and fix the problem from the inside
    B) Pick a new language that is more stable, platform-independent, and allows more control of object creation.
    C) Deal with it
    D) Post your overly-researched thoughts on improving existing languages to a website

    I don't investigate the intricacies of class libraries because someone else more knowledgeable than I took quite a bit of time writing, testing, and debugging them. I'm not saying to use anyone's class throughout your code blindly, but you are talking about the String library released by company who maintains the Java language. I say let it go, choose option B or C above and skip the self-induced migraines.



  • Its not so bad when you consider:

    class String {
        // snip
        String toString() {
            return this;
        }

       String valueOf(Object o) {
          return o == null ? "null" : o.toString();
       }
    }

    In other words, no String objects are created unless necessary, and nulls are handled somewhat gracefully by the + operator.

    The real WTF about string concatination in Java is the fact that its obviously operator overloading, bit it is without the flexibility of C++'s operator overloading, because its a special case only handler.  Although I see the value of a concatination operator, I think it would have been better to use a different symbol, instead of overloading the addition operator.  (Perhaps '..' would be a good candidate)



  • [quote user=WTF]garbage collection (which is a good thing, DrMindHacker)

    I assume that Mr Mindhacker meant Java's specific garbage implementation.

    I think we can all agree that garbage collection, in general, is a Good Thing™



  • Here's a quick lesson in OO:



    It doesn't matter.



    Unless you're using Java 1.1 on a 75 MHz Pentium, you won't be able to
    even detect the difference caused by the garbage collection.  The
    microseconds or nanosconds involved would be overshadowed by random CPU
    allocation by the OS for things like memory page updates or socket
    activity.



    You may want to do a search for "Premature optimization is the root of all evil" and note the purported sources.



  • @VGR said:

    Here's a quick lesson in OO:



    It doesn't matter.



    Unless you're using Java 1.1 on a 75 MHz Pentium, you won't be able to
    even detect the difference caused by the garbage collection.  The
    microseconds or nanosconds involved would be overshadowed by random CPU
    allocation by the OS for things like memory page updates or socket
    activity.



    You may want to do a search for "Premature optimization is the root of all evil" and note the purported sources.


    Who said GC was to make things faster?

    If there's no performance impact from GC, that's [i]very good[/i].



  • Yes, garbage collection is good for *other* reasons, such as vastly reducing memory leaks due to programmer error. They're still possible with GC, but highly rare. C programmers like to call that "lazy". I like to call C programmers masochists.



  • If you ask me, garbage collection is a double-edged sword that many novices are all too happy to fall on.



    On the one hand, you don't have to worry about who is creating objects
    and who is freeing them, which can become difficult to manage in large
    C/C++ projects (especially since there is no real convention followed,
    especially in our least-favorite operating system).



    One the other hand, you don't even think about who is creating
    objects.  Who knows how many temporary objects are being created
    in a single line of code (as shown above).  The cost here isn't
    just in the garbage collection itself (which, using reference counts,
    can be done VERY quickly and no more memory than a pointer).  The
    real cost is in the construction and destruction of objects. 
    Think of how many allocations are being made, constructors executed,
    data copied, virtual functions resolved, and types identified. 
    It's this whole hidden world that garbage collection allows to be kept
    hidden.  When you start making a bunch of lines with "new" on them
    for temporary objects, it becomes obvious that it would be a lot more
    efficient to work on the existing data.  But if the language
    doesn't even give you that option, or even just hides the fact that all
    these temporary objects are being made, who gives it a second thought?



    Java's major pitfall (aside from a lousy implementation) is that it
    abstracts too far from the hardware.  Once you have a language
    that handles everything automatically (in the most
    universally-acceptable way), you have something inherently inefficient
    and limited.  The same people who use Java would scoff at using VB
    or a shell script for the same tasks, and yet they scoff at them for
    many of the same inefficiency reasons.  C's advantage (amongst its
    many disadvantages) is that it forces you to be aware of what the
    system is doing.  It's not simple, but it's powerful and
    forthcoming.  It's the same reason hardcore programmers will drop
    to assembly language to ensure their code fits in cache, is word
    aligned, and everything else.  If it's built to handle every
    possible case, it's executing a lot more code than it needs to.



    This isn't meant to be a "C is better than Java" argument, just that
    its strengths in some areas (simplicity, platform-independence) must be
    compared to its weaknesses (larger, slower code).  Garbage
    collection is only just one area of Java where this becomes detrimental.



  • @VGR said:

    Here's a quick lesson in OO:



    It doesn't matter.



    Unless you're using Java 1.1 on a 75 MHz Pentium, you won't be able to
    even detect the difference caused by the garbage collection.  The
    microseconds or nanosconds involved would be overshadowed by random CPU
    allocation by the OS for things like memory page updates or socket
    activity.

    That's not completely true, there are some real-time systems out there that just can't bear with random garbage collection (and need the ability to explicitely and manually start and end the collection, as well as deterministic GCs).

    That's a very small subset of all the applications though. But the issue is real and completely independant from the hardware.



  • @RevEng said:

    Java's major pitfall (aside from a lousy implementation) is that it
    abstracts too far from the hardware.

    Java doesn't even abstract the hardware that much (it completely and stupidly abstracts the OS though, which is idiotic). Ruby, Python, Lisp, Scheme, and probably Haskell, Curry or Smalltalk do a far better job at abstracting the hardware.



  • @RevEng said:

    Java's major pitfall (aside from a lousy implementation) is that it
    abstracts too far from the hardware.  Once you have a language
    that handles everything automatically (in the most
    universally-acceptable way), you have something inherently inefficient
    and limited.  The same people who use Java would scoff at using VB
    or a shell script for the same tasks, and yet they scoff at them for
    many of the same inefficiency reasons.  C's advantage (amongst its
    many disadvantages) is that it forces you to be aware of what the
    system is doing.  It's not simple, but it's powerful and
    forthcoming.  It's the same reason hardcore programmers will drop
    to assembly language to ensure their code fits in cache, is word
    aligned, and everything else.  If it's built to handle every
    possible case, it's executing a lot more code than it needs to.



    This isn't meant to be a "C is better than Java" argument, just that
    its strengths in some areas (simplicity, platform-independence) must be
    compared to its weaknesses (larger, slower code).  Garbage
    collection is only just one area of Java where this becomes detrimental.







  • Forum ate the rest of the post...



    It is true that Java (and other high-level languages) allow the
    programmer to forget about details such as who's creating objects.
    However, it is still the programmer's responsibility to remove
    unnecessary object creations (and laziness, and boxing, and other
    implementation constructs introduced by languages which are
    higher-level than Java), in sections of code which need to be
    optimized. In most real programming languages, it is possible to create
    code with efficiency comparable to C just by thinking about
    efficiency
    . However, it is a great benefit of high-level languages
    that they allow you to forget about the optimization details, for the
    >90% of the program that doesn't need them.



  • @RevEng said:

    This isn't meant to be a "C is better than Java" argument, just that its strengths in some areas (simplicity, platform-independence) must be compared to its weaknesses (larger, slower code).  Garbage collection is only just one area of Java where this becomes detrimental.

    Garbage Collection is a two-edged sword, I'll give you that, but that doesn't make it bad. Pointers are equally a two-edged sword, and you claim they're a Good Thing (TM). They both are problematic and you have to pay careful attention to how you use them. On the one hand, with pointers you are free to do pretty much whatever you want. On the other hand, with pointers you are free to do pretty much whatever you want, and thus easily shoot yourself in the foot. Ditto Java: on the one hand, garbage collection allows you to not have to deal with pointers. On the other hand, garbage collection allows you to not have to *think* about object instantiation, and thus easily shoot yourself in the foot.

    The point: you can shoot yourself in the foot with either language. You can't claim GC is bad just because poor programmers can write bad code with it, just like Java enthusiasts can't claim pointers are bad just because poor programmers can write bad code with them.



  • I'd like to know, are we talking about GC in general, or just how Java, specifically, supposedly has bad GC?

    GC in general = Good Thing™

    GC implementation in Java = ?



  • @dhromed said:

    I'd like to know, are we talking about GC in general, or just how Java, specifically, supposedly has bad GC?

    GC in general = Good Thing™

    GC implementation in Java = ?

    I think RevEng was suggesting that GC in general is bad. I agree with you that in general GC is good. There are exceptional cases where it's necessary to *not* have GC, but for 99% of most programming, GC is better.

    I've never heard much about whether or not Java's GC is good or bad when compared to other platforms like .NET or python.





  • @RevEng said:

    One the other hand, you don't even think about who is creating
    objects.  Who knows how many temporary objects are being created
    in a single line of code (as shown above).  The cost here isn't
    just in the garbage collection itself.  The
    real cost is in the construction and destruction of objects.


    Compare the number (and severity) of problems caused by programs running a little slowly against the number (and severity) of problems caused by explicit allocation/deallocation being used incorrectly.

    Premature optimisation an' all that.



  • @jesuswaffle said:

    This may be worth a read: http://www-128.ibm.com/developerworks/java/library/j-jtp09275.html


    Wonderful!

    I feel smarter already.



  • @Whiskey Tango Foxtrot Over. said:

    I've never heard much about whether or not Java's GC is good or bad when compared to other platforms like .NET or python.

    The current Python GC being extremely crude (quite classic reference-counting, which may even have issues with circular reference when you fuck up C extensions) the Java GC is no doubt much better (I think java uses generational + mark&sweep, as does .net)

    The best garbage collection is to implement multiple garbage collection schemes switched at runtime when need varies, as does the MLTon SML compiler (it uses 3 or 4 different GC schemes and switches back and forth between them based on the current state of the system and objects)

    If you're interrested in garbage collection in general, I suggest that you read Garbage Collection: Algorithms for Automatic Memory Management by Richard Jones, one of the reference works on the subject. The GC article on Wikipedia is also fairly good, and has quite a lot of interresting links.



  • Couple of points...

    1) The Java doesn't define a specific garbage implementation. Anyone who create a JVM is free to create their own Garbage Collection implementation, as long as it conforms to the language standard.

    2) A possible reason why "String.valueOf(message).append(foo)..." is always used instead of the few cases where "message.concat(foo)"  might be better:

    Anyone can write their own core class libraries and distribute it with their own JVM => JRE
    So if I write a String class, which contains a valueOf(object) method, and a concat(object) method, I might rely on the fact that when String literal values are appended, the valueOf() mehtod is called, and not the concat() method.

    Is it likely that someone would rely on this? Who knows. If you read Raymond Chen, it looks like a lot of Win32 API programmers rely on weird, undocumented, non-standard features of that API. At least there is some consistency with Sun's implementation.

    And as a previous poster mentioned, freeing these short lived objects has a minor overhead. (creating lots of objects means that the garbage collector has to run more often, even if freeing the objects themselves has no overhead).



  • @thebilliardplayer said:

    If you read Raymond Chen, it looks like a lot of Win32 API programmers rely on weird, undocumented, non-standard features of that API.

    As a matter of fact, I do -- his blog pointed me to The Daily WTF.



  • Yes, Java's "garbage collection" implementation.  It is a very

    difficult thing to implement - it reminds of the brains "garbage

    collection" mechanism known as "sleeping".  It is very inefficient

    like Java.



    The brain undergoes sleep in order to filter collected input

    (forget) and retain input it considers relevent.  The problem

    is that the brain has to pretty much shutdown at a point

    when it becomes bogged down from a day - it puts you

    to sleep so it can utlize all resources to engage in this

    process of clearing out garbage memory.



    Java's "garbage collection" is the same.  At the point

    when it is most needed (lotsa memory to clear) is

    the point at which it is running least efficiently.



    Don't know if that other person's dangling reference

    to C programmers was pointing at me, but I am not

    only a C programmer, I also code in PERL, PHP, and

    JavaScript .



    Dr MindHacker

    Open Source Developer


Log in to reply