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.
-
This may be worth a read: http://www-128.ibm.com/developerworks/java/library/j-jtp09275.html
-
@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