Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!

 



Forgot your password?
typodupeerror
×
Java Programming IT Technology

Java Faster Than C++? 1270

jg21 writes "The Java platform has a stigma of being a poor performer, but these new performance benchmark tests suggest otherwise. CS major Keith Lea took time out from his studies at student at Rensselaer Polytechnic Institute in upstate New York's Tech Valley to take the benchmark code for C++ and Java from Doug Bagley's now outdated (Fall 2001) "Great Computer Language Shootout" and run the tests himself. His conclusions include 'no one should ever run the client JVM when given the choice,' and 'Java is significantly faster than optimized C++ in many cases.' Very enterprising performance benchmarking work. Lea is planning next on updating the benchmarks with VC++ compiler on Windows, with JDK 1.5 beta, and might also test with Intel C++ Compiler. This is all great - the more people who know about present-day Java performance, the better.""
This discussion has been archived. No new comments can be posted.

Java Faster Than C++?

Comments Filter:
  • Ah...yes... (Score:1, Insightful)

    by Anonymous Coward on Tuesday June 15, 2004 @05:29PM (#9435016)
    The great thing about language benchmarks is that there are so many to choose from...
  • by exp(pi*sqrt(163)) ( 613870 ) on Tuesday June 15, 2004 @05:30PM (#9435031) Journal
    ...on x86? Please! Wake me up when someone who knows enough about C++ to pick a decent x86 compiler runs some benchmarks.
  • by Anonymous Coward on Tuesday June 15, 2004 @05:32PM (#9435070)

    Java and C++ are language. Languages aren't "faster" or "slower", but compilers for them might be. I find it somewhat underhanded to put the languages in the header when it's really comparing compilers.

    Not to mention, inter-language compiler benchmark[et]ing is notoriously difficult to get 'right'. The programs tested are often stupid (doesn't do anything meaningful), or constructed by a person with more skill/bias for one language than the other.

  • -O3 (Score:1, Insightful)

    by Anonymous Coward on Tuesday June 15, 2004 @05:33PM (#9435078)
    If you care about run-time speed when using gcc you compile with -O3.

    I'd like to see the benchmarks redone with this.
  • Nice to hear... (Score:4, Insightful)

    by twocoasttb ( 601290 ) on Tuesday June 15, 2004 @05:33PM (#9435088)
    It's been ages since I've programmed in C++, but it's good to know see these favorable comparisons. I think about the Struts/Hibernate/Oracle applications I write today and shudder when I imagine what how difficult it would be to have to develop web applications in C++. C++ will be around forever and certainly has its place, but long live Java.
  • A few points... (Score:5, Insightful)

    by mindstrm ( 20013 ) on Tuesday June 15, 2004 @05:34PM (#9435107)
    There seem to be some unanswered questions here..

    - How equivalent were the benchmarks? Where they programmed in an optimum way for their respective compilers and libraries? I'm sure the java ones were.. what about the C++ ones? The author states he doesn't understand G++ very well.

    G++ is also known to not produce the best results.

    "I rant it with -O2"

    My guess is many of the tests were not implemented properly in c++.

    The main clue would be this... I can understand java having better than expected performance.. but there is no way I can accept that java is that much FASTER than properly done C++... it doesn't make any sense.

  • by saden1 ( 581102 ) on Tuesday June 15, 2004 @05:35PM (#9435119)
    I’m sorry but someone who says "I've never been very good at decoding GCC's error messages" is not competent enough to perform performance comparison. This performance test is a shame and shouldn’t be taken seriously.
  • Expert results (Score:5, Insightful)

    by otterpop81 ( 784896 ) on Tuesday June 15, 2004 @05:36PM (#9435145)
    Some of the C++ tests would not compile. I've never been very good at decoding GCC's error messages, so if I couldn't fix a test with a trivial modification, I didn't include it in my benchmarks.

    That's Great! I can't figure out GCC's error messages, but I offer definitive proof that Java is faster than C++. Nice.

  • Re:Sorry, no. (Score:2, Insightful)

    by kaffiene ( 38781 ) on Tuesday June 15, 2004 @05:37PM (#9435164)
    You're measuring startup time, not execution speed.

    Duh.
  • Flawed Test (Score:3, Insightful)

    by Emperor Shaddam IV ( 199709 ) on Tuesday June 15, 2004 @05:38PM (#9435182) Journal
    Comparing one C++ compiler (gcc) against the Java JVM on one operating system is not much of a test. I love Java, but this is almost something like microsoft would do. Test one specific OS, compiler, and configuration, and then make a blind, far-reaching statement. A fair test would include several platforms and compilers.
  • by mypalmike ( 454265 ) on Tuesday June 15, 2004 @05:40PM (#9435200) Homepage
    From methcall.cpp:

    int
    main(int argc, char *argv[]) {
    int n = ((argc == 2) ? atoi(argv[1]) : 1);

    bool val = true;
    >> Toggle *toggle = new Toggle(val);
    for (int i=0; i<n; i++) {
    val = toggle->activate().value();
    }
    cout << ((val) ? "true" : "false") << endl;
    delete toggle;

    val = true;
    NthToggle *ntoggle = new NthToggle(val, 3);
    for (int i=0; i<n; i++) {
    val = ntoggle->activate().value();
    }
    cout << ((val) ? "true" : "false") << endl;
    >> delete ntoggle;

    return 0;
    }

    Why allocate and deallocate an object within the scope of a function? Well, in C++, there's no reason, so this is bad code. You can just declare it as a non-pointer and it lives in stack space. But guess what? You can't do that in Java: all objects are allocated on the heap.

    That, and using cout instead of printf, are probably why this is slower than the "equivalent" Java.

    -_-_-
  • by 3770 ( 560838 ) on Tuesday June 15, 2004 @05:40PM (#9435210) Homepage
    Please point me to a source which verifies your claim.
  • by pclminion ( 145572 ) on Tuesday June 15, 2004 @05:42PM (#9435236)
    Talk about an unfair comparison... The C++ example uses the standard IO library, while the C example uses the UNIX write() call. Of course there's going to be overhead associated with using a buffered IO layer.

    This would be much more meaninful if you had used fputs() instead of write() in the C version.

    As for "several orders of magnitude," I call bullshit. There's no way in hell the standard C++ IO functions are hundreds of times slower unless they're extremely badly written. Which leads me to another reason why this example sucks: there can be different implementations of the standard libraries.

    In conclusion, this "comparison" is a stinky pile of shit, and should be ignored. And it's not even on topic, since it doesn't have a Java version.

  • by Anonymous Coward on Tuesday June 15, 2004 @05:42PM (#9435237)
    The JIT has run-time path information that g++ does not and can put parts of the hot path together so that they are the same page in cache. YEEEHAW
  • by I_Love_Pocky! ( 751171 ) on Tuesday June 15, 2004 @05:46PM (#9435284)
    All you programmers that say you can do anything in Java/C#/etc are terrible.

    Actually you can do most anything in those languages. Although for performance, and desgin reasons you may wish to use something else depending on the application.

    You have no respect for code. Learn assembly and then we'll talk.

    I know assembly, and fun as it is, it isn't well suited for high level projects where code reuse and mantainability are important. By the way, I have no respect for someone who knows assembly and thinks it is difficult. It isn't. And it certainly isn't graceful or elegant, but I love it all the same.
  • by Erwos ( 553607 ) on Tuesday June 15, 2004 @05:47PM (#9435305)
    I believe that Sun's javac bootstraps itself just like gcc does. That would be your java compiler written in Java.

    _Jikes_, OTOH, is written in C++. But that's not really the official Java compiler by a long shot.

    Your second requirement is absolutely bizarre. Does this mean you're not taking languages like Lisp, Prolog, Python, and Perl seriously, too? Those are all very nice languages for doing stuff in, but I'm pretty sure id never wrote a 3D engine in them. In fact, I was under the impression that id has never written a 3D engine in C++, either. Should we not take C++ seriously?

    IMHO: The measure of a language is not how easy it is to write an arbitrary application in it. It's how easy it is to write something for which the language was designed to do.

    -Erwos
  • by 3770 ( 560838 ) on Tuesday June 15, 2004 @05:50PM (#9435349) Homepage
    A few examples

    1) Java has bounds checking for arrays, C++ doesn't. This is specified in the language. This affects performance.
    2) Java has garbage collection, C++ doesn't. This is specified in the language. This affects performance.

    Also, the specification of Java says that it should be compiled to byte code and executed in a JVM.

    So the "language" certainly affects performance.
  • by FedeTXF ( 456407 ) on Tuesday June 15, 2004 @05:51PM (#9435365)
    I can say after using SWT in the Pocket PC platform that it sucks. The widgets are primitive, lack any real model implementation, they brake compatibility between minor versions, the most advanced things are done in the Eclipse UI packages not in the widget toolkit and the code you end up writting is ugly.

    Elaboration:
    No model: with swt you get the widget as a UI object with a field of type Object that you may or may not use as a reference to the object dislpayed. You ahve to write the code that updates th view when the underlying object changes and hende there is not real MVC pattern there. You can do it yourself. Imagine the huge pile of repeated effort in many projects around the world.

    Primitive widgets: the table widget is just a string grid. No masked text input, and it goes on and on.

    Ugly code: they use public fields for setting state to widgets not constructors or factory methods or even setters. They have integer constants for decribing widgets and you have to use those and see them. Creating a label requires using new Label(SWT.LABEL) and creating a horizontal Line is new Label(SWT.LABEL | SWT.HORIZONTAL). So much for hiding complexity.
    There are 4 type of layout managers, the initialization is verbose and in fact only 1 are relevant, GridLayout, the other 3 are special cases of the former.

    The more advanced widgets are not in SWT, only in the Eclipse centered custom libraried. The SWT mantainers say those classes are for use in the eclipse UI and they don't mean thme to be general purpose, use thej if they fit, but don't ask for improvements.

    The only way SWT is justified is when you have very low resources (a pocket pc) or need to compile with gjc. Otherwise, Swing is way better even when it is far from pefect.
  • by morcheeba ( 260908 ) * on Tuesday June 15, 2004 @05:52PM (#9435372) Journal
    Why did he use only -O2?

    -O3 adds function inlining and register renaming [gnu.org].

    Also, some of the code doesn't look too much of a test of the language, but more of a test of the libraries. Both versions of hash rely on the library implementations, and it looks like hash.cpp [kano.net] does an extra strdup that the java version doesn't. I don't know either of the hash libraries well enough, but I don't see why this significant slowdown would be necessary in the gcc version.
  • Re:Um, it's online (Score:5, Insightful)

    by jdhutchins ( 559010 ) on Tuesday June 15, 2004 @05:52PM (#9435374)
    Just becuase you can't write a kernel in it doesn't mean the language is worthless. There are many things that you can do very easily in Java that would be more difficult in other languages, and Java makes it impossible to write many security bugs that plague other languages. You can't do EVERYTHING in Java, but you can do quite a bit.
  • by Anonymous Coward on Tuesday June 15, 2004 @05:52PM (#9435381)
    But that's what 100% of all C++ programs on your Linux computer are compiled with.
  • Troll (Score:5, Insightful)

    by stratjakt ( 596332 ) on Tuesday June 15, 2004 @05:52PM (#9435390) Journal
    This test proves that Sun's optimized Java compiler and VM are faster on Red Hat than gcc.

    Gcc is designed for compatibility with a wide range of architectures, and is not optimized for a single one. He also (apparantly) used stock glibc from Red Hat. And only one "test", the method call test, showed java to be a real winner. And even then, it's server-side Java, which is meaning less when you talk about it as a day-to-day dev language (ie; creating standalone client-side apps).

    Intel's (heavily optimized) C++ compiler should be a damn sight faster, and so should VC++.

    This "comparison" is so limited in scope and meaning, that this writeup should be considered a troll.

    Hell, read his lead-in:

    "I was sick of hearing people say Java was slow, when I know it's pretty fast, so I took the benchmark code for C++ and Java from the now outdated Great Computer Language Shootout and ran the tests myself."


    Ie; I set out to prove Java is teh awesome and c++ is teh suck!

    If anything it proves something I've known intuitively for a long time. gcc does not produce x86 code that's as fast as it could be. That's a trade-off for it being able to compile for every friggin cpu under the sun.

    I can't wait till RMS takes personal offense and goes on the attack.
  • by cduffy ( 652 ) <charles+slashdot@dyfis.net> on Tuesday June 15, 2004 @05:53PM (#9435391)
    Well, yes, but the GUI issues are something completely different -- specifically, that Sun has no clue how to write a decent widget set, and insists on going either too far in one direction (AWT -- only supplying widgets available natively on every supported platform) or too far in another (Swing -- emulating every widget even on platforms where they're available natively).

    These benchmarks *didn't* include things like opening windows and so forth, and I think that's appropriate. Anyone who cares about writing a graphical Java app with decent performance should be using a different widget set anyhow, like IBM's SWT.
  • by cardshark2001 ( 444650 ) on Tuesday June 15, 2004 @05:53PM (#9435402)
    It's just not possible. It could be comparable, in limited cases, but not faster. It just can't be. If you find that it is, there's something wrong with your experiment. Does this mean Java is bad? Not necessarily. It depends on your purpose.

    Okay, so how could I make a blanket statement like that? In this case, the author of the paper merely used a compiler switch in gcc (-o2). That doesn't mean his c++ was highly optimized. It just means he told the compiler to do its best. If you really wanted to highly optimize c++, you would study the compiler and how it works, and you would profile the actual assembly that the compiler generates to make sure that it didn't do anything unexpected. Given *any* algorithm, I can come up with a c++ implementation that is faster than a Java implementation. Period.

    The java compiler actually compiles to a virtual opcode format, which is then interpreted by the java virtual machine at runtime. Imagine if you needed to talk to someone on the phone, but instead of talking to them, you had to talk through an intermediary. Is there any possible way that it could be faster than talking to the person directly?

    Now, I'll be the first to point out that a badly implemented c++ algorithm could be much slower than a well implemented Java algorithm, but I'll take the pepsi challenge with well written code any time, and win.

    Relying on benchmarks and code somebody else wrote doesn't prove anything. Did he get down and dirty with the compiler and look at the generated assembly code? No, he did not.

    Move along, there's nothing to see here.

  • SWT (Score:3, Insightful)

    by Master Of Ninja ( 521917 ) on Tuesday June 15, 2004 @05:54PM (#9435409)
    But until it is bundled by default with the JVM and JDKs, it will still be hassle to get SWT working for normal users. If Sun replaced the swing toolkit with SwingWT [sourceforge.net] and linked it to SWT, I would think there would be a great improvement in performance of most Java GUI apps (and most of them really do suck - the only good one I have seen is MoneyDance).
  • Bull hockey (Score:3, Insightful)

    by wurp ( 51446 ) on Tuesday June 15, 2004 @06:00PM (#9435474) Homepage
    If one program uses profiling information to run faster than another, it runs faster nonetheless. I agree with other posters that this is comparing compilation & runtime environments rather than languages, but when I care about how fast a program runs I care about how fast it runs, not how fast it would run in some hypothetical nonexistent environment. C++ would probably be faster if it had some kind of JIT environment to run in, but it doesn't, and as a developer trying to write fast software, that's what I care about.

    That said, I doubt the performance differences are enough to affect my decision about what language to use, unless I am writing some application that does enough computation that a person has to wait on the program, rather than the other way 'round.
  • by Anonymous Coward on Tuesday June 15, 2004 @06:03PM (#9435513)
    > By the sounds of it you have no idea what a good GUI is. Skins and themes do not a pretty UI make.

    Since Swing has all the GUI elements of every other toolkit, what would make a pretty UI if not skins/themes? A bad design can be done in any toolkit if the designer doesn't have a good sense of layout, etc.
  • by bgs4 ( 599215 ) on Tuesday June 15, 2004 @06:03PM (#9435515)
    Notice that the C++ methcall code declares "activate" a virtual function, but not so in the java version. No kidding you're going to get better performance.

    Presumably the java compiler inlined the function call. Do the math-- 4e9 function calls in 2.5 seconds. That's 1.6e9 function calls per second. On a 3.0 GhZ machine that's two cycles per call, so they're probably all inlined.

  • it's reasonable (Score:3, Insightful)

    by trance9 ( 10504 ) on Tuesday June 15, 2004 @06:03PM (#9435522) Homepage Journal
    In response to what many of you have and will write:

    -- there is not necessarily any "extra layer" created by the JVM. the whole idea is that the JVM is actually a run-time compiler, and when it's done compiling the .class to native code you really have native code directly executing.

    -- the JVM runtime compiler can perform optimizations that are not available to a C++ compiler. for example, if the JVM realizes that there is only one instance loaded of an abstract/virtual class it can compile all the code that accesses it statically against that single code, as if there were no inheritence at all, saving a pointer reference. a C++ compiler can never do that because it does not know what you will link against.

    -- Many of you are simply going to find ways to criticize Java because you are religious. You used to criticize performance, and if that is taken away from you, you will say it was never really important and criticize something else. You need to think whether or not you are being objective and rational, or simply theocratic.

    -- Yes you could likely optimize the C++ code better. Some suggested replacing the inefficient cout's with printf's but that is really eliminating the ++ part of the C++ language. If you can't take advantage of C++'s OO features then there isn't any point in comparing the language with Java--without those higher level features you are programming in the 70's. Guess what, assembler is even faster. So it is fair to compare C++'s high level features with Java.

    -- Repeat: Some of you are simply religious.
  • Re:Um, it's online (Score:3, Insightful)

    by poot_rootbeer ( 188613 ) on Tuesday June 15, 2004 @06:06PM (#9435550)
    until one can write an OS kernel in it, Java is still not what I would personally look to for the future of software development.

    That's a silly thing to say.

    How many OS kernels are going to be written in the next ten years? And how many business applications? And the ratio of the latter to the former is what, 10,000 to 1?
  • by giliath ( 200249 ) on Tuesday June 15, 2004 @06:07PM (#9435558)
    The -server mode of java causes the JVM to recompile code for the most used code path. I have not looked at the exact code for each of the tests, but in many cases this can result in the JVM optimizing out the code completely. You have to be extremely careful when doing benchmarking of languages like java because the JVM is able to dynamically recompile the code to remove the actual work, if the results of that work are never used.

    ~Giliath
  • by bpellin ( 128265 ) on Tuesday June 15, 2004 @06:09PM (#9435583)
    Certainly the language affects implementation. However, the only relevant speed comparisons are between implementations of a language. Saying that language requirements/features will have an effect on performance is misleading.

    For example, good JIT compilers for Java are able to eliminate many bounds checks for arrays. Consider something like:
    for (int i = 0; i < 10; i++) {
    A[i] = ...
    }
    If the array A is of size >= 10, the compiler can easily prove the checks unnecessary, and the generated code will not contain bounds checks.
  • On the flip side (Score:5, Insightful)

    by msgmonkey ( 599753 ) on Tuesday June 15, 2004 @06:12PM (#9435626)
    When C/C++ uses profiling it will only ever produce one "best case" compilation for a given function.

    With any JIT system you have the opertunity to use the profiling information from a given "window" of the execution so there is the possibility of having more than one compilation for a function.

    Now, I do not know how sophisticated JAVA JIT compilers have become but this is one area where JIT will have an upper hand over a static compiler.

    OTOH, these tests do not look like there is enough significant variation in the execution path for profiling to make a large difference.
  • Re:A few points... (Score:5, Insightful)

    by Trillan ( 597339 ) on Tuesday June 15, 2004 @06:14PM (#9435644) Homepage Journal

    Maybe it does make sense. But what it proves is that C++ (at least as implemented by GCC, but it's probably a design flaw) is slower than expected, not that Java is blazingly fast.

  • by kaffiene ( 38781 ) on Tuesday June 15, 2004 @06:15PM (#9435672)
    (1) Do a google for "runtime optimisation"

    (2) Get a clue
  • My Hero! (Score:5, Insightful)

    by 3770 ( 560838 ) on Tuesday June 15, 2004 @06:16PM (#9435676) Homepage
    No, I'm not being ironic.

    I'm tired of some programmers expecting to be worshipped because they know assembly.

    Assembly isn't all that.

    For some uses, it is the right tool. For 99.9%+ it most definitely isn't.
  • by Anonymous Coward on Tuesday June 15, 2004 @06:17PM (#9435689)
    How is this Informative ? An object in C++ is only constructed when the code flow reaches the point where the variable is defined. So if you put a stack object inside that if, it only gets built inside that branch, and you have the benefit of skipping it for the common cases, while still avoiding the heap.
  • by Waffle Iron ( 339739 ) on Tuesday June 15, 2004 @06:17PM (#9435696)
    There is no one answer to the question "which language is faster?". It all depends on that the workload is.

    For example, Java with its JIT can easily match a C compiler on bit-banging and number crunching small data sets when there's no memory allocation going on. However, that isn't what most people are waiting for when they run typical interactive applications.

    If a system is not I/O bound, most applications tend to be doing a lot of string manipulation or similar operations on small objects. When Java operates on strings, it tends to create, discard and garbage-collect a large number of short-lived string objects because Java's strings are immutable. This consumes quite a bit of CPU and memory.

    Some C++ applications are written the same way. Many KDE applications are rather sluggish, probably because they are taking advantage of a lot of automatic management of a lot of QT objects. STL-based C++ apps can also be sluggish if you use high-level containers like tree maps without a keen awareness about what kinds of extra copying and thrashing can happen under the hood when you use them. Even in C, if you use high-level libraries, you can get sluggish performance, as some of the more bloated Gnome apps demonstrate.

    However, C++ programs, even STL-based ones, may also be written in a different style that takes advantage of mutable strings and handles object allocation manually. This tends to reuse data structures in place, eliminating memory management overhead, and it has the very important effect of keeping caches and page tables much more localized. This is more bug-prone than the alternative, but can provide a substantial performance improvement that Java can't hope to touch on a similar dataset. The drawback is that the app is much more likely to crash unless it was written by a top-notch developer; in fact, this kind of programming is the cause of many of the security problems plaguing the various OSes over the years.

    (People often point out that nobody writes kernels in Java. That's because they tend to be written using the manual memory management style with as many static data structures as possible to squeeze out more performance. People don't use popular high-level C++ libraries to write kernels for the same reasons.)

    Bottom line, the answer to which language is faster will always be "it depends". It depends on what the program is doing, and it depends on how the program was written. A couple of datapoints from a language shootout don't help to resolve the issues.

  • Unix GUIs are far easier to implement with Java than with C++. Athena/Xlib are a huge fargin' hassle and no-one ever gets the widgets right. Motif is too expensive to license.

    You really need to look into Qt. It's much easier to use than Swing.

  • by SuperKendall ( 25149 ) * on Tuesday June 15, 2004 @06:20PM (#9435726)
    You are once again spouting the tired old line that Sun is the master of Java. Not at all true, Java's fate is controlled by a whole host of companies - including IBM. Take a look at the reality of Java platform evolution at the Java Community Process [jcp.org] web site.

    It's a standards body just like any other, just more open.

    P.S. - Aside from that gripe being wrong, I agree with the other poster that you should look into Objective-C to address other issues. Look for "GnuSTEP" for cross-platform objective C GUI work. It's just nicer to use on a Mac as they have very good tools (though in fairness I have never looked at what GnuSTEP tools might be around, I just can't imagine them being quite as good as the tools Apple has sunk so much effort into!).
  • by SuperKendall ( 25149 ) * on Tuesday June 15, 2004 @06:25PM (#9435780)
    I had similar experiences writing a Swing app around six years ago (just around the release of 1.2). At first the Swing app was a little slow, but after a number of rounds of profiling and tuning it was really, really fast - with an MDI interfance and a lot of heavily customized controls on very busy forms. The app worked great even on slower computers, and was well received by the client.

    There is no reason Java has to be slow. It's just prone to having a lot of layers stuck on things when they might not need to be. As you say, for a lot of work people are doing J2EE stuff may well be overkill (though even that can work with simialr efforts to tune).

    Basically, with any VM app tuning is key. As C# people are only just now starting to realize... a shame the tools there are a lot more primitive that what Java has to offer.
  • by iapetus ( 24050 ) on Tuesday June 15, 2004 @06:26PM (#9435797) Homepage
    If that's the approach you're going to take, though, then you might as well just code in assembly - cut out the middle man. Benchmarks like this are entirely worthless - the main thing they do is stir up the rabid language zealots out there, 5% of whom will be crying from the rooftops that it's all a lie and C++ is better, 2% of whom will be insisting that the results cast Java in a bad light and that it should be seventeen times faster than C++, the other 93% will be pimping their own language of choice.

    At the end of the day, the real question that I should be asking myself is which language gives me the best balance of maintainability, ease of development and elegance of expression. I don't care if you can shave two instructions from your generated assembly code at the cost of making your code ugly as hell and impossible to maintain. This is a bad trade-off that only matters to the most anal of benchmarkers and those rare few who really do need the absolute maximum performance from a (typically small) segment of their code. I want to know which language is going to make me most productive, and there's no objective measure of that which I trust as far as I can throw it.
  • Re:A few points... (Score:3, Insightful)

    by maraist ( 68387 ) * <michael.maraistN ... m ['AMg' in gap]> on Tuesday June 15, 2004 @06:28PM (#9435823) Homepage
    Except that in enterprise computing (as opposed to scientific computing), we are not interested in JUST throughput, but more often the time-to-shipment of the application, and the robustness of the code. Robust code is often abstracted or is littered with superfelous code (i.e. redundant checks for nullity).

    Code that is easy to read, easy to maintain is often not very performant, because you aren't allowed to make special-case optimizations at the code level, since they are often a nightmare for other's to interpret.

    In terms of efficient elegant code, it is trivial to use a hash table over a linked list in java (in fact, linked lists are harder to implement). Thus a LOT of java code uses such O(k) algorithms. On the other hand, in c it's relatively easier to use bitmaps than a hashed set, and thus c has less overhead for a common practice. But, as a consequence, bitmaps often have an upper-bound (no more than 32 entries) (yes, I know you can use bitmapped c structures). But a hash table is easier to read and harder to screw up than a boolean-logic bitmap, so it is often a better choice for "enterprise code".

    So my response is that it depends on how you define "efficient programming". Do you mean efficient execution (which really is optimized programming), or efficient writing and maintanance of code. I suspect you mean the former, but what you should mean is the latter.

    What's more, as far as a business man, you have to weigh the cost of development time v.s. performance of application. Well written non buggy, easily adaptable code requires little future man hours, and can take advantage of moore's law. If the software is successful, "scaleable" code can run on ever more expensive hardware (clustering). Highly optimized software may not be easily clusterable, or may not lend well to adaptations; each adaptation would require re-optimizing the code. The classic example here is Java's "Reflections", where a text configuration file is often used to link unrelated code together. I see this a lot in databases where we map new tables to code which may or may not be a proper fit.. The reflective configuration handles the remainder of the impedence mismatching. Note that you can do this in c as well, but it wouldn't be the fastest solution by far.
  • by adiposity ( 684943 ) on Tuesday June 15, 2004 @06:31PM (#9435854)
    What concerns me most is the amount of memory it requires. In theory, once the requisite stuff is loaded into memory, Java byte code can be processed at nearly the same rate that C++ code is. Depending on the bytecode and assembly that are generated in each case, Java or C++ could end up being faster. I think it's obvious that Java incurs some overhead in translating the bytecode, which ought to slow it down *some*, but that amount can be minimized.

    On the other hand, Java takes a great deal of memory. If C++ had a dedicated server sitting in memory, ready to execute commands for it, it probably would speed up execution, but that wouldn't mean C++ were faster.

    After accepting the memory hit for Java, the performance on things like apps servers seems to be pretty decent. I have yet to use a java client application, however, where I didn't feel that it was sluggish (even after loading). There are only two explanations: all java code is written poorly, or Java inherently causes a performance hit.

    As we abstract languages more and more, we see performance hits for increased functionality and ease of developing. We also see that, because of the easier development, it is easier to improve scalability and use more efficient algorithms. It is rare that a program cannot be sped up by hand-optimizing the assembly, but it is also rare that anyone has time to design the much more critical optimized algorithms at such a low level. Therefore, I predict that eventually Java (or something like it) will be embraced as programmer time matters more than speed of execution.

    The one thing that disturbs me about Java is that, while in C++, it is easy to change the assembly while maintaining the C/C++ code, in Java, you are tied to platform-independent code, which prevents you from doing platform specific optimizations. You have to depend on the native java implementations and/or widget toolkits for those kind of things. And so far, although the situation is improving, I've been pretty unhappy with the speed and my ability to improve it.

    -Dan
  • by ChaosDiscord ( 4913 ) on Tuesday June 15, 2004 @06:37PM (#9435909) Homepage Journal
    You would do it if you need a scrap object only sometimes (and didn't want to pay the overhead penalty of instantiating it every time the proc got called).

    If it's C++, you can scope the variable to the block you need it in. The object should not be instantiated until (and if) the block is entered. C++ scoping fills me with more happiness than is probably healthy. The idiom "/* Read the file */; { FileLockObject thelock(filename); ReadFile(filename); }" is just so wonderfully clean. No matter how you exit the block (return, continue, break, throw), the lock is released immediately.

    Of course, your point is still valid. In more complicated functions you might have an object that is optionally created and must visible throughout a larger block or function. In that case, yes, you'd do exactly what you suggest. I've certainly done it myself.

    BigObject * tmp = 0;
    if(RareCondition()) {

    tmp = new BigObject;
    }
  • by cyfer2000 ( 548592 ) on Tuesday June 15, 2004 @06:38PM (#9435933) Journal

    "Hi, I am a professor from X university, and I was wondering if we could get a license of your compiler for research?"

    "I am sorry, blah blah blah..."

    "May I talk with your boss?"

    "Sure, just a second...du...du..."

    "Hi, can I help you?"

    "Hi, I am a professor from X university, and I was wondering if we could get a license of your compiler for research?"

    "Ah...May I know your research topic?"

    "It's about the speed of C++ and java...blah blah blah"

    "As a company sponsored a lot of research, you know, we'd like to support your research, but, you know...blah blah blah."

    "So how much it could be?"

    "something between your arm and your leg"

    "I am going to think about it, thank you for your help, have a nice day"

    "you too, feel free to contact us, bye."

    "Bye"

    "OK, boy, we use gcc firstly, and after we got enough funding, we may buy a better compiler!"

    "Yes, sir, and the result of GCC is here."

    "Nice..."

  • Cross platform (Score:2, Insightful)

    by Psymunn ( 778581 ) on Tuesday June 15, 2004 @06:39PM (#9435934)
    C++ is as cross platform as the libraries you use. The game code i'm writing so far (it's a simple game, doesn't have any assmebly or optimisation... just a keen like side scroller) compiles under both windows and linux. Using the same make file. How? I use SDL for everything. I've had equally pleasent experiences with Qt. Portability in C and C++ is all based on the libraries.
    Of course being able to compile on multiple platforms and being cross platform aren't the same thing but I still think that it is in the benefit of people producing software for Linux specifically, to write code that will port to Windows without to much avail (who the hell uses \?)
  • That's not useful.

    void foo() {
    ...
    if ( SomeRareCondition() ) {
    AReallyNastyObject temp;
    ...
    }
    ...
    }

    does essentially the same thing, but is less error-prone than an operator new/operator delete pair -- consider what happens if an exception occurs between your new and delete.

    There's basically no reason to allocate a single object using new and delete it within the same scope. Allocating arrays, or allocating an object for use in a different scope, are okay.

  • by Get Behind the Mule ( 61986 ) on Tuesday June 15, 2004 @06:59PM (#9436155)
    Whew, there's seems to be a lot of denial running through this thread. "An interpreted language just can't possibly be as fast or faster as a compiled language! So I just don't care what the empirical results say, no matter how badly or well done they are, it just can't possibly be!"

    I think some of you are overlooking the fact that a VM running byte code is capable of doing optimizations that a compiled language just can't possibly do. A compiled language can only be optimized at compile time. Those optimizations may be very sophisticated, but they can never be any better than an educated guess about what's going to happen at runtime.

    But a VM is capable of determining exactly what is happening at runtime; it doesn't have to guess. And thus it is able to optimize those sections of code that really are, in true fact, impacting performance most severely. In can do this by compiling those sections to machine code, thus exploiting precisely the advantage that a compiled language is alleged to have by its very nature. And other kinds of optimizations, the kind that a compiler traditionally does, can be performed on those sections as well.

    Of course there are scenarios where runtime optimization doesn't win much, for example in a program that is run once on a small amount of data and then stopped, so that the profiler doesn't get much useful info to work with. This is why Java is more likely to have benefits like this in long-running server processes.

    And of course a conscientious C++ programmer will run a profiler on his program on a lot of sample data, and go about optimizing the slowest parts. A conscientious Java programmer should do that too. But an interpreted language has the advantage that the VM can do a lot of that work for you, and always does it at runtime, which is when it really counts.
  • Benchmarks... (Score:3, Insightful)

    by abertoll ( 460221 ) on Tuesday June 15, 2004 @06:59PM (#9436156) Homepage Journal
    A langauge in and of itself does not determine the speed. It's how that language is implemented/compiled. There's no reason why Java SHOULD be slower as long as it is compiled to the machine's architecture, and not to byte code. ... but then that destroys the purpose of Java.

  • by sysopd ( 617656 ) on Tuesday June 15, 2004 @07:02PM (#9436188)
    I wish all Unix GUIs were done in Java.

    That line made my blood curdle. Of all the UNIX apps I've used, the ones that were written in Java are my least favorite and least used apps. I prefer apps written in C with a toolkit like Qt or Gtk+. Both of those are exceptionally fast and modern looking. Toolkits like WxWindows compile natively with no extra dynamic libraries required and are crossplatform.

    But as anyone really using *NIX knows (yes I'm talking about you gentoo, sourcemage, LFS and slackware guys), you always pick the app written in C before the app linked against libstdc++. It may sound elitist but it just seems that people writing in C know what they're doing and take the time to write more solid code. Not to say you can't write a crapwagon C program, perhaps its just easier to fuck it up when you're writing C++.

    To go back to your line that made me choke, "I wish all Unix GUIs were done in Java." Perhaps large one-off or custom design software could benefit from Java. But I think this is the minority not the rule. The apps I use on a daily basis are the window manager, xterms, media players, web browsers, document viewing/creation apps, etc. These types of apps have matured over the last 10 years and are all (the ones I use at least) written in C. That is why I can use X and actually do work with no problems on my P133 laptop. Compare that to OpenOffice, Limewire, etc al that I would not touch with a 10' pole for fear of my laptop shutting itself quickly and breaking off my fingers in retaliation.

  • Re:Sorry, no. (Score:3, Insightful)

    by kraut ( 2788 ) on Tuesday June 15, 2004 @07:02PM (#9436190)
    >A VM otoh does get this capability for free.
    TANSTAAFL ;)

    > Java enforces garbage collection, and thus optionally gets the particular performance gain
    Err... whether garbage collection gains or looses you performance depends very much on your application. I am not convinced that any garbage collector can even be theoretically faster than automatic variables.

    >As was pointed out, one of the strenghts of C/C++ are pass-by-value....
    After programming in C++ for 14 years, I don't think I've heard that one before

    >The fact that you have to explicity declare a c++ parameter as pass-by-reference suggests that those interested in "good programming practices" (tm) will only make a pass-by-reference if you intend to modify it's contents
    const &? Ever heard of const references before? I don't feel qualified to judge your Java programming, but it's evident you're not particularly familiar with C++.

    I'd be interested to know how you have more control over the design of 3rd party libraries in Java than in C++.
  • by rjh ( 40933 ) <rjh@sixdemonbag.org> on Tuesday June 15, 2004 @07:02PM (#9436195)
    My prior message might not have shown why it's not wise to build a C++ iostreams implementation on top of the conventional C facilities. So let's try something nice and simple.
    char *foo = "Hello, World!\n";
    printf("%s", foo);
    Straightforward, right? So here's the question: when does the program figure out how to display foo?

    The answer is--at runtime. Printf takes two arguments, has to evaluate them, has to parse the format string, has to figure out how to splice the data into the format string, etc., etc. (Note that printf doesn't even know what kind of data you're giving it; it literally has to interpret the parameter list at runtime. That's the major performance problem with vararg functions.) Compare this to
    std::string foo("Hello, World!");
    std::cout << foo << std::endl;
    ... where, thanks to C++'s much superior type system, the C++ compiler knows at compile-time that foo is a string, and that allows the C++ iostreams facility to generate much better code than the C-style "let's figure everything out at runtime" way.

    Short version: a decent implementation of C++ iostreams will wipe the floor with C-style I/O. If you're seeing performance penalties from C++ iostreams, the first thing you should do is make sure the problem isn't in your own code; the second thing you should do is make sure your iostreams library isn't built on C libraries that determine type information at runtime.
  • by xp ( 146294 ) on Tuesday June 15, 2004 @07:03PM (#9436201) Homepage Journal
    Here is an excerpt from the article for this story: Lea used G++ (GCC) 3.3.1 20030930 (with glibc 2.3.2-98) for the C++, with the -O2 flag (for both i386 and i686). He compiled the Java code normally with the Sun Java 1.4.2_01 compiler, and ran it with the Sun 1.4.2_01 JVM. He ran the tests on Red Hat Linux 9 / Fedora Test1 with the 2.4.20-20.9 kernel on a T30 laptop. The laptop "has a Pentium 4 mobile chip, 512MB of memory, a sort of slow disk," he notes.

    What this shows is that GCC's implementation of C++ is slower than an interpreted language like Java. This does not show that C++ is slower than Java.

    ----
    Notes on Stuff [blogspot.com]
  • Actually, you're wrong, at least in part. Due to lack of specificity, I'd say that invalidates your argument.

    It's all about *where* and *how* Java is used.

    As someone who has done application development with both Java and C++ (as well as C, and others), here is how it works (assuming equivalent levels of code quality regardless of language):

    For a non-GUI application, Java can be made to run nearly as fast as C++, with a slight startup penalty, and while utilizing decidedly more RAM.

    For a GUI applicaton, Java will run considerably slower than a C++ application, and use significantly more RAM.

    What does this mean?

    Java works great for back-end applications, for web applications, etc. Especially if you take into consideration it's startup penalty (time needed to start the JVM) and run your java program persistently, Java can definitely be fast enough for this.

    As for GUI applications, Java is only an ideal choice if you absolutely need something that is fully cross-platform (without using multiple binaries for each), for small applications, or for situations where you can gaurantee that the client machine will have a LOT of RAM, and a fairly modern CPU.

    Now, use which ever langauge makes the most sense for what you're doing, and let's get back to coding, okay?
  • by Cthefuture ( 665326 ) on Tuesday June 15, 2004 @07:06PM (#9436242)
    I just went through and tested the hash2 benchmark and found that I was correct. The C++ version slaughters the Java version (even in "server" mode). This is completely different than what this dude's page shows.

    Here is the "correct" code for hash2.cpp:

    #include <stdio.h>
    #include <iostream>
    #include <ext/hash_map>

    using namespace std;
    using namespace __gnu_cxx;

    struct eqstr {
    bool operator()(const char* s1, const char* s2) const {
    return strcmp(s1, s2) == 0;
    }
    };

    struct hashme
    {
    size_t operator()(const char* s) const
    {
    size_t i;
    for (i = 0; *s; s++)
    i = 31 * i + *s;
    return i;
    }
    };

    int
    main(int argc, char *argv[]) {
    int n = ((argc == 2) ? atoi(argv[1]) : 1);
    char buf[16];
    typedef hash_map<const char*, int, hashme, eqstr> HM;
    HM hash1, hash2;

    for (int i=0; i<10000; i++) {
    sprintf(buf, "foo_%d", i);
    hash1[strdup(buf)] = i;
    }
    for (int i=0; i<n; i++) {
    for (HM::iterator k = hash1.begin(); k != hash1.end(); ++k) {
    hash2[(*k).first] += k->second;
    }
    }
    cout << hash1["foo_1"] << " " << hash1["foo_9999"] << " "
    << hash2["foo_1"] << " " << hash2["foo_9999"] << endl;
    }

  • by TRACK-YOUR-POSITION ( 553878 ) on Tuesday June 15, 2004 @07:24PM (#9436434)
    A third one I think is really important

    3) All Java classes are the equivalent of C++ virtual classes. There's a whole lot of dynamic type-checking, virtual function table lookups, and so forth when dealing with any Java objects, right?

    Which is what is striking to me about these benchmarks--there's all kinds of sorts and matrices and pure number crunching stuff, but I didn't see anything in which garbage collection or object management delays would start to become apparent. If what the other poster says about avoiding bounds checking is correct, that means that these benchmarks managed to avoid the major potential liabilities of Java performance.

    That's not to undermine the significance of these benchmarks--it's still very interesting that Java can approach and perhaps surpass C++ performance in any case with JIT.

  • Re:Sorry, no. (Score:1, Insightful)

    by 0x0d0a ( 568518 ) on Tuesday June 15, 2004 @07:29PM (#9436481) Journal
    It might become less significant.

    But I get cranky when I click a button and the application doesn't, y'know, appear.

    If I have to wait for 19 seconds for anything to appear, I'm not going to be a happy camper, ignoring what technical reasons cause the slowdown.

    Furthermore, from a technical standpoint, Java has a number of fundamental performance flaws:

    * Java bounds-checks all array accesses. This is pretty par for the course for safe languages, and it's a good bet that compilers optimize some of this out, but it's a hit.

    * Java technically can avoid rapid allocation/deallocation by use of object pools and use of primitives and the like. However, it's *very easy* to have an excessive number of allocation/deallocations. The language definitely encourages this.

    * Java lacks generics (I haven't checked out 1.5, not sure whether this can provide performance improvements). This is bad because casting and hence run-time typechecking has to take place every time an object in a container is accessed.

    Plus, Java eats memory for breakfast. Yes, memory is cheap and all that, but as a user, I'd definitely take a C/C++ app over a Java app any day.

    Java's great for lightweight networking, it's nice that it has a cross-platform GUI, and it's good for rapid development due to the scads of library functionality.

    The problem is that it got way overhyped as a C/C++ replacement (which it isn't) or even a good choice for general application development (including horizontal-market client stuff) which it isn't.
  • Re:Um, it's online (Score:3, Insightful)

    by Anonymous Coward on Tuesday June 15, 2004 @07:33PM (#9436503)
    Thank you! I am not the only one that noticed that these are not even equivilant code. Using sprintf when you expect speed is stupid. sprintf is for simplicity. Making 5 function calls in the middle of a for loop when once would have been fine is also stupid. Also Gxx type compilers are KNOWN to be slower. They are getting better. But the 3.3 branch is more of a staging for better things to come. I would be interested in the same thing done with the intel compiler. WITH all the sub libraries compiled with the intel compiler.

    Sure the code does the same thing. But the few code bits I looked at are not identical. To be a 'fair' test. All the functions need to be written in the same file. Then with *VERY* minimal changes work in both java and C. It wasn't even C++ code. Also if he used the G++ compiler? That is *KNOWN* to be very slow. They rewrote the sucker for 3.4. All the functions need to be called in the same way. All the loops need to be walked the same way. Etc...

    This test is bogus. I was willing to give the dude a listen. He even tries to defend what he does wrong. Its almost pathetic. For example he talks about GCC vs Visual studio. Then goes on to use G++. Interesting... Another good thing he does to 'obscure' the issues is to use overloads in C++ yet use method calls in Java. overloads are much slower. Usually firing off all sorts of copy constructors. Method calls are much faster. He even admits it C++ is faster in one case. Well that ONE case is about the only one where he has apples to apples. The rest are not. Also his 'method call' test is not the same thing. He did it in such a way that fires at least 2 copy constructors in the C++ way yet returns direct objects in the java way. C++ is slower in those cases. Well DUH.

    The idea that java or .net could catch up to C performance is interesting though. The code in these enviroents could be self tuning themselves. Did he prove that? I do not think so. NOT with that code.

    It is like I have always said. C/C++ does not produce awsome code. It lets you produce awsome code. But if your not carefull it lets you produce extreemly BAD code. It does not hold your hand. It has never claimed to. I could with a little bit of work (not as hard as some people would assume) produce the EXACT oposite results of what he got.
  • Re:Um, it's online (Score:4, Insightful)

    by ThosLives ( 686517 ) on Tuesday June 15, 2004 @07:38PM (#9436548) Journal
    I agree about the non-equivalent code:

    A fun one:
    Java:

    public static int Ack(int m, int n)
    {
    return (m == 0) ? (n + 1) : ((n == 0) ? Ack(m-1, 1) : Ack(m-1, Ack(m, n - 1)));
    }

    C++:

    int Ack(int M, int N) {
    return(M ? (Ack(M-1,N ? Ack(M,(N-1)) : 1)) : N+1);
    }

    The C++ version could have been written IDENTICALLY (except for the 'public' modifier on the definition) to the Java version, but it was not. I'm not sure what the compiled difference might be, but there is a difference between these two bits of code, notably that in the C++ version there is a tertiary operator evaluated as an argument to a call to Ack, where this is not the case in the Java version. I would guess that this would be a more difficult thing for a compiler to figure out.

    The differences in the methcall sources are even worse; in the C++ version of NthToggle, there are unnecessary dereferences of the this pointer that will kill performance, as well as in the call to new NthToggle(val, 3) in the C++ version is written with the coded constant new NthToggle(true,3) in the java version! It's hardly fair to compare things of this nature.

    The trouble with benchmarking different languages is hard enough due to inherent differences between languages; it's not really enlightening to introduce artificial differences such as these.

  • Re:My Hero! (Score:3, Insightful)

    by 3770 ( 560838 ) on Tuesday June 15, 2004 @07:45PM (#9436607) Homepage
    I know assembly and I have studied CPU designs. I also know compiler technology and I have written a compiler (commercially).

    I abide by the rule "to write simple code and only optimize when needed" and it has worked great for me.

    I'm not crapping on those that know assembly, only those who think that it gives them a right to look down on those that don't.

    I stand by my rant.
  • by Serveert ( 102805 ) on Tuesday June 15, 2004 @08:11PM (#9436816)
    sprintf(buf, "%x", i);

    It must parse the "%x" and determine what it's trying to do. So it decides, at runtime, you want to translate an integer value into a hexidecimal string. Of course if there's an error at runtime in the string "..." it must generate an error. How 'bout using strtol?

    Now let's look at the java version:

    Integer.toString(i, 16)

    Ok, here we have something that is strongly typed so of course it will be faster. At runtime the java compiler _knows_ what it's dealing with and it knows it must invoke the hexadecimal conversion code.

    Note that these statements are within loops.

    Just one example, that was the first file I looked at. I don't think they have quite optimized the C++ code IMO. Plus the C++ library is notoriously slow, I would recommend rogue wave or your homegrown C++ classes.

    I think the lesson here is it's very easy to write slow C++ code while it's very easy to write fast Java code.

    Gimme any C++ code here and I'll profile it/speed it up and get it as fast if not faster than java.
  • Java to Assembly (Score:4, Insightful)

    by HopeOS ( 74340 ) on Tuesday June 15, 2004 @08:12PM (#9436823)
    It should also be mentioned that the java language requires specific overhead to be included that C++ and C do not. Even if compiled down to sleak assembly, Java is still saddled with doing bounds checking.

    The rest of the performance improvements are in the compiler optimizations and libraries which are mostly tangential to the language itself. If the compiler is clever enough to take "for (x=0, i=0; i<100; ++i) x+=5;" and substitute this for "x=500;", then great, but it should not be confused with an endorsement of the language itself.

    Furthermore, I had no difficulty modifying the C++ code to outperform or at least meet the results of the server-side JVM using G++. In the cases where Java had any lead whatsoever, the code was so trivial that the JVM could virtually precompute the result. I don't see this as being useful because in the real-world, nothing I write is so trivial that this is possible. If it was, I would have done it myself. I believe this largely explains the discrepency between these "tests" and my actual experience.

    -Hope
  • by mangu ( 126918 ) on Tuesday June 15, 2004 @08:23PM (#9436923)
    Yes, of course, the recursive Fibonacci is slow. But the point was measuring the efficiency of the compilers, not the efficiency of the code. Do you want a much faster Fibonacci algorithm? Here it is:


    double gold = (1.0 + sqrt(5)) / 2.0;


    int fibonacci(int n)

    {

    return floor(gold * n);

    }

  • Re:A few points... (Score:3, Insightful)

    by GooberToo ( 74388 ) on Tuesday June 15, 2004 @08:27PM (#9436957)
    but there is no way I can accept that java is that much FASTER than properly done C++

    Well, bluntly, you need to better understand the technology so you can adjust your expectations. While I've only started looking at the code, it does appear that these benchmarks represent many ideal situations whereby java's hotspot technology can make many aggressive optimizations.

    These benchmarks, by no stretch of the imagination mean that Java is faster than C++. It does, however, clearly show that in ideal situations, hotspot can clearly make huge leaps in performance.

    Worth noting, psyco for python (a hot-spot "like" technology), also has ideal situations where it actually performs faster than c. Again, this is because it's able to more aggressively optimize in certain situations with more knowledge than the compiler had during compilation. Does this mean that, in whole, python+psyco is also faster than c? Of course not. But, it certainly does lend support to the notion that java and it's hot spot technology can not be dismissed out right, as I see many racing to do.

    The big question, which I currently do not have an answer to is, do these benchmarks have any meaning in the least, in the real world? If so, in what situations do they reflect?

    In stead of panicing about these results, let's take them for what they are, lick on a grain of salt whlie we're at it, and figure out if they mean anything in the real world. I suspect that they don't, but that's just my bias talking. In the mean time, I'm going to be looking at some code.
  • Re:Sorry, no. (Score:3, Insightful)

    by maraist ( 68387 ) * <michael.maraistN ... m ['AMg' in gap]> on Tuesday June 15, 2004 @08:30PM (#9436980) Homepage
    While you make several good points. I do have some counter-points.

    A VM otoh does get this capability for free.

    Let me qualify this as saying you don't have to do or pay for anything extra to achieve this.

    Err... whether garbage collection gains or looses you performance depends very much on your application. I am not convinced that any garbage collector can even be theoretically faster than automatic variables.

    By automatic, if you mean stack-resident variables, then I agree (with the caveat of dangerous code design), but if you mean malloc'd variables, then I don't see what the problem is. malloc has to worry about a great number of things, not least of which is memory fragmentation. I happen to have done a non-trivial amount of research on memory allocators; though I am no expert. Memory allocators can be optimized for allocation speed, fragmentation efficiency, concurrency, cache coherence, etc. but not all (obviously). As it happens, a copying garbage collector gives you all of the above EXCEPT when your buffer runs out; and thereby requires a garbage collection. So long as you you have large heap and you're not worried about the latency from garbage collection, then copying collectors are VERY fast. Allocation is literally a mutex lock, a stack-pointer range check, a stack-pointer increment, then a mutex unlock.

    Now, because latency is often a real issue, most modern GC's apply additional complexity/logic which slows down the normal case to minimize the worst case; e.g. generational garbage collection which may require read or write boundry op-codes inserted. But code-wise, these varients are identical. Thus you achieve a flexibility not possible in a dynamic-memory-egnostic system such as c/c++.

    I'd be interested to know how you have more control over the design of 3rd party libraries in Java than in C++

    I didn't really mean design, but environment; Specifically in terms of the dynamic memory allocator. But, just to make the differentiation complete, java allows byte-code load-time modification. This is very common in "aspect oriented programming" such as in the database realm (JBoss/OJB) or object proxying. In Java, by introspection you can prepend/append/search-replace method calls or even individual instructions as need be. Note that this isn't any different than a custom pre-processor for C, but tends to be cleaner and thus doesn't require the [3rd party] coder to adhere to a particular convention.. Moreoever, this works on already shipped binaries, as opposed to requireing preprocessing to occur on the original source code.

  • That's all true.. (Score:2, Insightful)

    by mindstrm ( 20013 ) on Tuesday June 15, 2004 @09:12PM (#9437287)
    but that's nto the same thing as saying "Java is faster than C++". The benchmarks in question are bout execution speed, not development speed.

    Some of the benchmarks could have been far better implmented with code no more complex than what was arleady used on the c++ side... that's the issue here.

    "java is faster for lazy coders" is a fair statement.. but not really what a benchmark tries to asess.
  • The cout is done twice, and the new and delete are each done only once. They are not the reason for the poor performance.

    Sure cout is done twice, but it uses 'endl' where '\n' would do. 'endl' flushes the stream, which pretty much kills cache behavior. When the disk/console is orders of magnitude slower than the CPU, a single 'endl' can indeed kill performance.

    As for new/delete, they can also be very slow, depending on the current memory layout, etc. More importantly, they violate the C++ programming paradigm (local objects not allocated on the heap) and hence are indicators that this isn't a very good C++ programmer, and hence he isn't qualified to make a reasonable comparison.

    Shoot, the last time I did the Java/C++ flamewar I found that Python was faster than both (reading and sorting strings).

  • Re:Um, it's online (Score:3, Insightful)

    by GooberToo ( 74388 ) on Tuesday June 15, 2004 @10:34PM (#9437877)
    That's not a bug in the tests, it's a feature.

    That's simply not true if you expect benchmarks to reflect real world applications. Sure, it might be true for trivial utilities but for applications that stay alive for long periods of time chugging along, which is probably the majority of the worlds useful applications, it makes the results invalid. Or, at a minimum, sets greatly unrealistic expectations.

    The theory behind garbage collection isn't just that it allows the programmer to avoid the effort of watching when to delete things. It's that garbage collection can actually improve performance on certain workloads.

    This is true..."on some workloads". I certainly recognize that fact. I hoped I had more or less pointed that out in my original message. At any rate, for real world workloads, I would offer that such expectations are not realistic.

    Forcing a garbage collection for every delete is completely unfair, since it does a full scan of memory, as opposed to just twiddling bits to free a single data value.

    Well, technically, even with the 1:1 implementation, it's not forcing collection. It's actually hinting to the GC system, that it should consider doing so. The GC is 100% free to ignore such a request. This is per the java specifications. Which, makes plenty of sense because doing so tends to greatly increase the window where GC can improve performance in various workloads. The problem is, I honestly don't know where implementation and specification lay. I've read many times that it actually does ONLY result in a hint to collect. Unless you can prove otherwise, I'm apt to lean in that direction. Which, actually means that the 1:1 implementation is a more realisitic apples to apples comparison. Can I prove that? No. I'm still hoping a java guru will come in with some insightful tidbits. ;)

    There's no memory leak for these benchmarks... both C++ and Java free all memory used when the process exits. Perhaps you'd prefer a longer-running test with lot of garbage generation (forcing gc to run at some point).

    Yes, I'm aware that there are no leaks. That's not my complaint. My complaint is that just about every java benchmark I've ever seen is so artificially small that they all appear to purposely avoid GC ever becoming part of the benchmark. Since most major applications simple don't start, run for 20 seconds and exit, I don't consider the presumed bevaior to be valid.

    The secondary point I was attempting to raise (along with awareness to the hidden gc issue) is that once Java is forced to start collecting, it's pays a significant cost. A cost, I'd hazzard a guess, that brings about the common complaints of Java. And that, I offer, is the difference between labratory tests and real world application. ;)

  • Re:Um, it's online (Score:3, Insightful)

    by Trepalium ( 109107 ) on Tuesday June 15, 2004 @11:04PM (#9438129)
    That's not a bug in the tests, it's a feature.

    It's neither a bug, nor is a feature. It's a difference, and possibly a testing methodology flaw.

    The theory behind garbage collection isn't just that it allows the programmer to avoid the effort of watching when to delete things. It's that garbage collection can actually improve performance on certain workloads.

    And on certain workloads it can decrease performance. Coders that know their languages should recognise the difference between the two memory allocation methods, and adjust their code accordingly. I seriously doubt you'd claim that java's garbage collector is always faster than manual memory management.

    Forcing a garbage collection for every delete is completely unfair, since it does a full scan of memory, as opposed to just twiddling bits to free a single data value.

    Perhaps, but it's also unfair to have a 'benchmark' that always pays the penalty of C++ memory allocation and deallocation, but never pays the penalty of Java memory allocation and deallocation.

    There's no memory leak for these benchmarks... both C++ and Java free all memory used when the process exits. Perhaps you'd prefer a longer-running test with lot of garbage generation (forcing gc to run at some point).

    Just because the memory is freed back to the system after termination doesn't mean it isn't a memory leak. It's a bad practice to allocation memory and not free it when you're writing C or C++ code. A longer running process would probably be more fair, or even a garbage collect at the end of execution. After all, on 'real' programs, a garbage collection is quite likely.

  • by cardshark2001 ( 444650 ) on Wednesday June 16, 2004 @12:59AM (#9438832)
    I'd like to see a C++ implementation of the Halting Problem

    Eh.... so for your counter example you choose a problem that is unsolvable in any language?

    Did you just read about that in your computer science class or something? How does that relate to the question at hand? For any java implementation, of any algorithm, I (or someone else) can write a c++ implementation that is faster. Does this mean that I can solve problems in c++ that are unsolvable? Ummm.... no.

    This is a common logical fallacy. Its Latin name is "Non-Sequitur". You'll probably get to that next year when you study logic.

  • Re:Um, it's online (Score:5, Insightful)

    by jovlinger ( 55075 ) on Wednesday June 16, 2004 @01:01AM (#9438840) Homepage
    "Any sufficiently complicated C or Fortran program contains an ad hoc informally-specified bug-ridden slow implementation of half of Common Lisp." -- Philip Greenspun

    / took way too long to google
  • by Ytsejam-03 ( 720340 ) on Wednesday June 16, 2004 @01:55AM (#9439116)
    The fact that Java VMs are primarily written in C or C++ indicates that at the time they were initially written, it was believed (I think correctly) that the C or C++ at that time would be a better platform for writing JVMs than the Java of that time, and that since then it has been considered better to extend the existing code than to scrap it and do a complete rewrite in Java.

    That's all that this argument proves. Nothing more.

    What I'm saying, though, should not be interpreted as a belief that today's Java would be a better choice than today's C++ for writing a Java JVM. I don't know what the relative advantages would be today.
    Am I missing something, or did you just suggest writing a JVM in Java? Which language will you use to implement the JVM that will run your Java-implemented JVM?

    My understanding is that JVM performance has improved because they are now doing things like selecting the appropriate instruction set for the processor at runtime. This is opposed to natively complied languages which are typically compiled to support the lowest common denominator.
  • Tools (Score:2, Insightful)

    by Myolp ( 525784 ) on Wednesday June 16, 2004 @02:33AM (#9439285)
    Something that is almost always ignored when comparing programming language is the actual cost of developing something in that language.

    Sure, you can almost always produce faster software in a low-level language. But since there are no good tools for doing this, it costs to much. Developing software using a modern, state-of-the-art IDE like IntelliJ IDEA, NetBeans or Eclipse speeds up the actually development process and allows the programmers to focus on the design, rather than trying to understand an obscure low-level API.

    And no, Visual Studio does not count as a state-of-the-art IDE...
  • Re:it's reasonable (Score:3, Insightful)

    by cardshark2001 ( 444650 ) on Wednesday June 16, 2004 @03:06AM (#9439424)
    What you're basically saying is if I want to hand optimize every line of code I write, rather than concentrating on the task at hand, then I should use C++, but if I want the compiler to do the heavy lifting then I should use Java?

    No, I'm not saying that at all. I'm saying Java can be faster, in some circumstances, if you are talking about a naive implementation. I never said that Java would always be faster, and I hardly think that is the case (some undergrad troll who made the front page of /. notwithstanding).

    However, when you need the utmost in performance, and second best won't cut it (and assembly is too much hassle), c++ is your best choice. Do you think Doom 3 could possibly be written in java? I'll answer that one for you - no way in hell. To suggest otherwise is ignorant and ludicrous at best, trolling at worst.

  • by mc6809e ( 214243 ) on Wednesday June 16, 2004 @03:18AM (#9439470)
    I notice that much of the overhead is simply in making function calls.

    Ackermann.cpp, for example, spends very little time actually calculating anything. Much of it's work includes all the overhead associated with making a function call.

    Included in this overhead is management of the frame pointer. By using -fomit-frame-pointer, you avoid pushing the old ebp on the stack and a store of the current esp into ebp.

    Ackermann runs about twice as fast with this simple optimization.

  • Bullshit (Score:3, Insightful)

    by baest ( 763283 ) on Wednesday June 16, 2004 @03:19AM (#9439479)

    I saw this test a few days ago and wanted to check it out. The first thing I realize is that the source code is somewhat different even if Java has almost the same syntax as C++.

    I understand that System.out.println(); is not in C++ but why have

    return(M ? (Ack(M-1,N ? Ack(M,(N-1)) : 1)) : N+1);
    instead of
    return (m == 0) ? (n + 1) : ((n == 0) ? Ack(m-1, 1) : Ack(m-1, Ack(m, n - 1)));

    I made the C++ code look like Java and got a 15% save. Problably even more if I had increased the number you call the program with. I looked at some of the other program and they have different code in them as well. So this test is bullshit it only shows that you can make slow programs in any language.

  • Re:Um, it's online (Score:2, Insightful)

    by Sinterklaas ( 729850 ) on Wednesday June 16, 2004 @04:22AM (#9439691)
    Calling System.gc() will usually result in a collection. The VM can't know whether a garbage collect will be useful, because only a full mark and sweep will reveal that. Thus, while the docs state that garbage collection will not necessarily happen after a call to System.gc(), all current VMs will do a full gc (AFAIK). That makes sense because the programmer can determine the need better than the VM.

    The JVM is designed to make most efficient use of the available RAM and calling System.gc() totally defeats that. To 'forbid' Java from doing it's thing is as fair as disallowing the C++ from using pointers, non-objects (except primitives) and other features which can't be found in Java. Obviously, that is wrong because those features make C++ what it is, just like (unforced) gc is an inherent part of Java.

    The only way to determine what the effects are of garbage collection vs (de)allocation is to design a benchmark specifically for this purpose. For instance, you could handle some big images and see how fast each language can complete the benchmark. Another interesting benchmark is to handle a large amount of small objects. However, in the end, the effect of garbage collection on real world apps can differ greatly, depending on:
    - the total amount of memory the app can use
    - the number of allocated objects
    - the size of objects
    - the lifetime of objects (Java is far more efficient with short-lived objects, for which it uses a mini-heap and mini-gc)
    - the workload of the app (can it do garbage collection during a time of low load?)

    The results can differ greatly depending on the particular situation that you are looking at. Of course, it is true in general that it is rare for a language to be better on all fronts, so you always need to look at what you want to do and how well the language is suited to do that. That is also the reason why I hate broad generalizations like:

    Sadly, I'm once again seriously disappointed in Java.

    Just because the benchmark is flawed, doesn't mean that Java was somehow bad. Especially since your benchmark was a thousand times more flawed. Since you have shown little knowledge about Java (every beginning Java programmer learns that you should avoid calling gc directly), I suggest you stop making these stupid comments. /end rant
  • Re:Um, it's online (Score:1, Insightful)

    by Anonymous Coward on Wednesday June 16, 2004 @04:26AM (#9439713)
    Garbage collection has long be heralded as a faster solution than explicit new/delete handling of memory allocation. Adding System.gc() is dumb. Escape analysis in the JVM means explicit deletes are placed in where an object clearly doesn't escape a particular level of Java's scope. You can improve GC and escape analysis by assigning object references the value of null.
  • Re:Troll (Score:2, Insightful)

    by KZigurs ( 638781 ) on Wednesday June 16, 2004 @04:42AM (#9439773)
    " And even then, it's server-side Java, which is meaning less when you talk about it as a day-to-day dev language (ie; creating standalone client-side apps)."

    As far as I understand ONLY field where Java can be used succesfully now IS THE server side. And believe me - there is way more ordinary programmers that happily crunch their daily duties creating xml/xsl/html/xhtml/whatever spitting JSP's or servlets than hardcore C++ GUI developers.

    Of course this will probably change once Java will get something decent for graphics, maybe even Qt in native Java... Existing graphical layers are simply sickening to work with.

    But for everything else - there is a nice, decently fast (and believe me - you DO NOT need those 16xCPU power5 grids or that 8.244012% difference in execution speed - when developing you always should be looking for simplest/easiest and most practical solution. At least in the main cases. It MAY be different if you are one of CuBase developers.).

  • Re:Um, it's online (Score:3, Insightful)

    by nikster ( 462799 ) on Wednesday June 16, 2004 @05:12AM (#9439892) Homepage
    I'm seeing the benchmarks take serious advantage of java's GC mechanism
    the first part of your analysis is sound: the benchmarks are highly questionable since the Java code never runs the gc, thereby cheating it's way out of having to do mem management.
    very good point.
    Worse, when I ran it with a 1:1 ratio of delete:System.gc(),
    so, you took it back to Java, and biased the test in favor of C++ by running way too many gc's, which, as you point out don't even mean anything because the gc doesn't get invoked immediately. by adding System.gc() to the Java side of the test, you in fact added some kind of randomizer to the code. you don't know what System.gc() does - it's a notification that the gc may run, yes. But you don't know what exactly the system will do after it's called. For all you know, it could stall for a couple of seconds. Or it could count all objects in memory. Or... anything. You added a random delay to the Java side of things.
    and, lo and behold, you "proved" that c++ is faster. now, if the original comparison was biased, this was surely worse.

    a better test would probably be to let the c++ side never collect anything. and to stop the watch before java starts collecting (just use a huge max. heap size and set it to use the traditional gc and it won't collect anything for a while).

    Regarding the article: It's kind of silly to count the JVM startup delay in the tests. Because for some things it will matter, e.g. programs that get run, then shut down again zillions of times. That's why you can't write command line tools in Java. For other things it won't matter at all because they get started once and then continue running (client-GUI software, server app). Also, new JVMs from Apple (and Sun, in the future) just won't have the startup delay because they will statically link precompiled versions of the java class library (rt.jar).

    IMHO, speed matters only in one area: When doing calculations in tight loops. There, i believe Java is just as good as c++ because the hotspot compiler actually works and will generate fast, optimized assembler code out of the java loop.

    I did some unrelated speed tests within Java (checking the overhead of final method calls - it turned out to be zero as it gets optimized away) and found out, to my surprise, that a simple calculation in a for-loop ran at 400 million loop iterations per second, or 1/3 of phyiscal machine speed (1.3GHz Pentium-M). I found that impressive. Come to think of it, it was probably exactly the DRAM access speed (i was accessing a huge array).
  • by Get Behind the Mule ( 61986 ) on Wednesday June 16, 2004 @05:55AM (#9440023)
    Now, have you really thought this out?


    Sure have, friend, so let me respond with another question: Did you read my post? It seems that you've completely missed the point.

    First of all, I wasn't talking about Java and C++ so specifically, but rather about running byte code on a virtual machines vs. running machine code directly. When the VM is running byte code, it can profile the actual behavior of the program and optimize the sections that really are the slowest. A compiler that translates to machine code cannot do this, it can only guess at the best optimizations.

    Let's turn the languages around. Suppose we write a VM in Java, which runs byte code compiled from C++ programs. Then it can profile the running C++ byte code and optimize the critical sections. A C++ compiler that translates directly to machine code cannot do that.

    Understood this time?

  • I'm sorry, but I am afraid you are wrong.

    Well, I know the halting problem and I don't see how it relates to what you're saying. The conversion from recursive to iterative isn't arbitrarily complex, it's simple and mechanical. The easiest way is to simply use a stack to maintain the state of what were previously recursive calls.

    This is still recursion. You have simply substituted one stack for another.

    Anyways, all the halting problem implies is that an optimizer will never be able to find every situation where a particular optimization is applicable.

    No, it implies much more than this.

    Deciding whether two programs are equivalent(EQTM) is equivalent to ATM (the halting problem). (I'll give the series of proofs if anyone requests it.)

    This means that there is no algorithmic way to transform recursive functions into iterative ones, and any substitution must be based upon matching of patterns pre-coded into the compiler.

  • by mactari ( 220786 ) <rufwork AT gmail DOT com> on Wednesday June 16, 2004 @09:40AM (#9441183) Homepage
    What's important to note is that the differences introduced by the VM and the rest of Java's overhead are small enough now that, for headless applications, poor coding can easily bridge the difference. There's no huge, glaring, a priori reason to use C++ over Java for headless apps, and when you want your server code to be portable crossplatform you'll find a huge, glaring reason to use Java.

    Now what this study obviously doesn't deal at all with GUI'd applications, and Sun's Swing in particular does nothing to help Java's reputation as a slow technology. There's a relatively interesting discussion at java.net called Swing Usability [java.net] that points out some of these shortcomings. What the Swing team doesn't seem to understand is that slower than native means slow to most users.

    And just like the comments in this thread point out, as long as you put a compatibility layer between code and execution, you're going to be slower by definition. With Swing, simple to overlook unoptimized coding practices do not easily spell the difference between implementations. Here, Java's speed and performance is visibly slower no matter how quickly the GUI-less logic behind is racing along. (Yes, SWT is a big help, but it's not part of the JDK and likely still won't be seen in, say, Limewire [limewire.com] any time soon.)
  • Re:Um, it's online (Score:2, Insightful)

    by netstat ( 692739 ) on Wednesday June 16, 2004 @10:12AM (#9441468)
    The garbage collector runs in a low priority thread. If you just run some code that is doing nothing but calling System.gc(), then of course it will be called. However, if your code is actually trying to do something else, it really is just a "hint" as the other poster stated.
  • Re:Tools (Score:3, Insightful)

    by SnapShot ( 171582 ) on Wednesday June 16, 2004 @10:13AM (#9441480)
    Similarly, something this is also almost always ignored when comparing languages is the actual cost of developing something using the libraries available to that language.

    Back in the dark ages (late 80's) I learned to program in Basic, then Pascal, then ADA, then C, then C++ through high school and college. It must of been 8 years of part-time messing around with code before I wrote my first GUI (I luv that MFC!!!).

    Two days after picking up a Java book, I was doing (crappy but they worked) GUIs in Java.

    Two days after that I had database access through JDBC.

    Then is was XML parsing.

    Then is socket communication.

    Then J2EE...

    With every one of these libraries, a critic could potentially have a complaint that "Sun's implementation of X isn't nearly as good as library Y". However, they are available for free to any developer who has Java, they are documented in a thousand books about java, and the Javadoc web pages make sure there is a common way to access the knowledge necessary to learn new features.

    That, I think, is Java's greatest strength. Sure, Qt, Fox, MFC, GTK, Win32, or whatever may be a better (in your opinion) GUI library, but Swing is available to anyone who programs Java on just about any platform. I bet there are some custom ODBC-like drivers that squeeze the last ounce of performance out of your database system, but I bet I can have database access implemented in Java befor you have managed to get the purchase request for your ODBC library past the financial people.

    So, leave the arguments on who can leverage the last performance boost out of a language to the Comp. Sci. PhDs and researchers. If you, like me, are working in a business environment where success is measured in getting a working product out the door that meets the client's requirements, focus on the libraries you have available rather than the language. By that metric, Java comes out near the top.
  • Your other assertion here is that a recursive algorithm rewritten iteratively is still recursive if you don't do anything more complicated than maintain the state with a stack. Well this is not true. A function that does not invoke itself is not recursive, period.

    Depends how you define recursion. The prescence of a stack which maintains states means that the function *is* invoking itself. It's just doing so in the same frame on the main stack.

    Externalizing the stack *is* more effecient. But it is still, in any meaningful sense of the term, recursive.

    In fact just by looking at some (non-recursive) function that uses a stack, and judging that it could obviously be rewritten as recursion, you are finding an equivalance between them, which according to you is impossible.

    You have misunderstood the meaning of the term "undecideable". Please see my other reply for the details of how this works.

  • by CoughDropAddict ( 40792 ) on Wednesday June 16, 2004 @12:35PM (#9443124) Homepage
    Given *any* algorithm, I can come up with a c++ implementation that is faster than a Java implementation. Period.
    I'd like to see a C++ implementation of the Halting Problem that's faster than a Java implementation, please, thank you.

    Oh, wait, you can't do that because nobody can write Halting.

    I guess that means there are some algorithms for which you can't write a faster C++ version.

    Actually his statement still holds. No algorithm exists that can decide the halting problem, so he can still say "for all algorithms, a C++ implementation can be written that is faster than a Java implementation."

    But don't let me get in the way of you admiring how wise you are.

    Next time, try less rhetoric and more facts. "There exist lots of algorithms for which I can code a C++ implementation that's faster than a Java implementation" is good. The instant you make a unilateral statement like the one you just made, though, it shows that you don't know as much about computer science as you think you know.

    Get off it. Apparently you don't know as much about logical reasoning as you thought, or even Computer Science since you tried to call the halting problem an algorithm. Not to mention that the word "unilateral" makes no sense in this context; you probably meant "unequivocal" or "unqualified." Shall I find more things to pick on?

    (Normally I wouldn't be this pedantic, but you are ripping on someone else based on pedantry and being rewarded with +5.)

    Fact: there exist cases where Java is faster due to its ability to optimize on the fly.

    The whole point of this critique is that any run-time optimization that Java can perform, a human can perform when they write the algorithm. In the end, all programs are executed by running machine instructions, and any set of instructions that a JVM emits/executes, a human can write manually to achieve exactly the same performance.

He has not acquired a fortune; the fortune has acquired him. -- Bion

Working...