Follow Slashdot stories on Twitter

 



Forgot your password?
typodupeerror
×
Java Programming

Java Performance Urban Legends 632

An anonymous reader writes "Urban legends are kind of like mind viruses; even though we know they are probably not true, we often can't resist the urge to retell them (and thus infect other gullible "hosts") because they make for such good storytelling. Most urban legends have some basis in fact, which only makes them harder to stamp out. Unfortunately, many pointers and tips about Java performance tuning are a lot like urban legends -- someone, somewhere, passes on a "tip" that has (or had) some basis in fact, but through its continued retelling, has lost what truth it once contained. This article examines some of these urban performance legends and sets the record straight."
This discussion has been archived. No new comments can be posted.

Java Performance Urban Legends

Comments Filter:
  • by Anonymous Coward on Saturday May 17, 2003 @10:30PM (#5983537)
    SWT isn't platform-dependent. Look it up.
  • Java vs. RAM (Score:5, Informative)

    by kwerle ( 39371 ) <kurt@CircleW.org> on Saturday May 17, 2003 @10:32PM (#5983549) Homepage Journal
    has poor start up time, and requires an absolutely massive amount of memory. That, and garbage collection makes almost-real time ("soft" real time I believe is the technical term) UIs more difficult than they should be.

    Oh, good, another one to shoot down. While I don't have any numbers at all, I know that Apple 'fixed' this problem to an extent by making parts of java shared, just like any shlibs. This alleviates the 14 apps, 14 bags of shit problem to some extent.

    Apple then returned the changes to SUN, who rolled them into 1.4.x.

    I wish I had numbers. Sorry.
  • Re:Java is slow (Score:4, Informative)

    by etymxris ( 121288 ) on Saturday May 17, 2003 @10:35PM (#5983556)
    This is flat out wrong, what is "heavy processing", please describe what causes your machines to run out of memory?
    This is simple. Here are some examples I worked on:
    1. A tax adapter that did operations for each order. Setting a load tester against the server caused the machine to max out on memory. So I eventually had to create my own pool of objects to stop them from getting touched by the garbage collector.
    2. Text parsing/processing that operates on each line of many megabyte files. When done with mutable String objects, it kept increasing memory as a function of time, never reducing the memory load. It's not like I kept references to these objects. I had to reprogram it to not keep allocating objects for each line.
    I'm sure others have their own examples to contribute.
  • Re:Java is slow (Score:5, Informative)

    by larry bagina ( 561269 ) on Saturday May 17, 2003 @10:36PM (#5983565) Journal
    I think he's talking about something like this:

    while(true)
    {
    Object o = new Object();
    /* snip */
    o = null;
    }

    The GC won't free the memory in realtime (or, sometimes, ever), as would be the case for C++/C with new/delete malloc/free.
  • by Effugas ( 2378 ) on Saturday May 17, 2003 @10:57PM (#5983646) Homepage
    If you're going to rebutt some urban legends, perhaps it might help to go online, check out Snopes, learn how to argue against things...

    Yeah. Lets look at this article:

    Myth 1: Synchronization Is Really Slow
    a) Ummm, well it was slow...but not anymore!
    b) As the programmer, you have no idea what code is eventually going to be run. (Who knows! It might be FAST!)
    c) Who cares about the actual numbers; it's only a constant overhead! (This is actually a good point -- the sync'd method isn't doing anything, so the syncing can't amortize its penalty across any amount of work. But...still..."regardless of the actual numbers"?!?)
    d) But...but...you need to sync! Your programs will crash if you don't!

    Myth 2: Declaring methods "final" speeds them up
    a) Nuh-uh!
    b) I don't see a benchmark anywhere! (Nor, apparently, can I write one.)
    c) But...but...what if someone wants to extend your class?

    Myth 3: Immutable Objects are bad for performance
    a) It could be faster. It could be slower. Maybe you won't be able to detect a difference.
    b) The myth comes from a fundamental truth about how Java does many things really really slowly.
    c) StringBuffer creates objects too...ummm...in the corner case where the default buffer size isn't big enough to handle the added data, and the buffer wasn't preconfigured to store sufficient amount of data...heh! Look over there! *runs away*
    d) As the programmer, you have no idea what the garbage collector is eventually going to do. (Who knows! It might be FAST!)
    e) But...but...you're sacrificing object oriented principals!

    I was really waiitng for Myth 4..."Who needs performance! It's a Multi-Gigahertz PAHHHTAY!!!" But apparently that got cut.

    I've got a data point for 'em. You know Nokia's n-Gage Gameboy Killer? Hehhehe. Not _only_ did they completely forget to throw in any hardware acceleration for sprites -- heh, an ARM is fast enough -- but it looks like you're supposed to write games in Java.

    So, yeah. Puzzle Bobble @ 5fps. But I'm sure it's very elegant code :-)

    --Dan

    P.S. On the flip side, I'm playing with an app whose 2D GUI was designed with GL4Java...it's a work of art; faster than Win32, at least for tree manipulation. Java can be a beautiful language once its relieved of the duty of actually computing anything...
  • Re:Java is slow (Score:2, Informative)

    by Curt Cox ( 199406 ) <curtcox@@@gmail...com> on Saturday May 17, 2003 @11:04PM (#5983668)
    Not to be a pedant, but I doubt either of these were GC bugs.
    1. Your description is a bit too vague, for me to guess with much certainty. I bet you had some finalize methods that were preventing the GC thread from reclaiming your objects fast enough. This situation should be easier to diagnose and prevent than Sun currently makes it, but it isn't really a GC bug. Effective Java has a nice write-up on this problem. If you really think it is a GC bug, try creating a simple test case that demonstrates it. Java has plenty of bugs, but in my experience, trying to construct a simple test case for submission to Bug Parade will often demonstrate that you didn't really understand the problem.
    2. This sounds quite a bit like either this [sun.com] bug, or a close cousin. It is quite nasty, but really a bug in the java.lang.String code, and not in the GC.
  • Re:Java is Slow (Score:1, Informative)

    by Anonymous Coward on Saturday May 17, 2003 @11:15PM (#5983710)
    I know it's a joke (and I'd mod it up if I could) but for those that are completely clueless...

    JAVA was slow about 8 years ago, when most people who would have been early adopters where making their mind up whether to adopt JAVA or not.

    Those that did, did so because the programming lanugage itself included features which made the worst kinds of common mistakes in C and C++ go away. Those that didn't, didn't because JAVA suffered from problems that are common to any new language. Unfortunately the extreme media spotlight and pressure to use the new (to most at that time) techniques of OOP only made the latter group dig in their heels and avoid any acknolwedgement that JAVA has (or even could) improve.

    It's the same kind of mindframe that still has our company operating at half duplex (since a network card we bought in '92 dropped packets like crazy on full)
  • Re:Java is Slow (Score:5, Informative)

    by CyberGarp ( 242942 ) <Shawn AT Garbett DOT org> on Saturday May 17, 2003 @11:32PM (#5983783) Homepage

    I've worked on two embedded projects using Java on low power (energy consumption/CPU performance both) platforms. Both projects had amazingly similar things happen. I stated up from, "Java is interpreted; it will be slower than the C code of the previous project on the platform, potentially significant."

    The reply, "We don't care about performance."

    Four months later... "Why the hell is your code so slow?"

    Interpreted is as interpreted does.

  • by Anonymous Coward on Saturday May 17, 2003 @11:38PM (#5983799)
    You might want to check out the Colt libraries at http://hoschek.home.cern.ch/hoschek/colt/ [home.cern.ch]

    They're open source libraries for high performance scientific computing in Java and fairly easy to use at that.
  • by Anonymous Coward on Saturday May 17, 2003 @11:38PM (#5983804)
    While MySQL has transactions, it does not have ANSI standard transactions. They are implemented using a non-standard syntax and they don't follow the standard behavior rules.

    ANSI SQL:

    BEGIN TRANSACTION;
    BEGIN TRANSACTION;
    DELETE FROM Table1;
    COMMIT TRANSACTION;
    ROLLBACK TRANSACTION;


    MySQL:

    BEGIN;
    BEGIN;
    DELETE FROM Table1;
    COMMIT;
    ROLLBACK;


    The differences here are two fold. As you can see MySQL's syntax differs from that of normal ANSI SQL so you lose portability. Secondly MySQL permanently makes changes to the data at the first COMMIT statement so the changes can't be subsequently rolled back.

    In ANSI SQL no changes would have been applied to the data after this batch completed. In MySQL your data would be gone.

    Another point in this is MySQL's handling of corruption. It is mentioned that if you perform a full backup and keep the binary logging turned on that you can restore from the backup and replay the activity of the day. Apart from being a manual task it can be a lengthy task. Other databases simply restore themselves to the last known good state. In both cases some data will be lost, but at least in the latter case sleep wont be lost from a phone call at 4:00 AM.
  • by dirtydamo ( 160364 ) on Saturday May 17, 2003 @11:55PM (#5983873)
    The most common thing I believe about Java is that its performance is well below FORTRAN or even C for numerically intensive work, such as linear algebra on gigabyte complex matrices.

    I am not a fan of Java by any stretch of the imagination, but this is completely wrong.

    The latest JITs are unbelievably good at optimizing pure computation-based code, like numerics. In some cases, Java can be much faster than C (it surprised me the first time I saw this!).

    Java's problems are still:
    1.) Long start up time (but once it gets started, the number-crunching is good).

    2.) The garbage collector.

    3.) Large memory footprint.

    And all the other stuff other people have mentioned...
  • The article is wrong (Score:5, Informative)

    by jdennett ( 157516 ) on Sunday May 18, 2003 @12:10AM (#5983928)
    In a real project, using JDK 1.3 on various platforms, we had performance issues. So, we measured speed in various ways, and found three main problems.

    1: Synchronization.

    This is slow. Really slow. And it just gets worse when you're running on dual or quad processor machines. StringBuffer is a major offender; in a lame attempt to save one object allocation, it uses a simple reference counting device which requires synchronization for operations as trivial as appending a character. Writing a simple UnsynchronizedStringBuffer gave a measurable performance boost.

    2: Object creation

    This is the real problem. GC is slow. GC on SMP machines is still really slow in JDK 1.3 -- maybe JDK 1.4 is better, my experience is a little out of date. By rewriting large chunks of code to create fewer objects (often by using arrays of primitives) we made it much faster -- close to twice as fast, if memory serves.

    3: Immutable objects

    Yes, these add to GC, and so are bad for performance. But not such a great evil, so long as you don't overuse them.

    Funny that the article "debunks" these myths without figures, when our thorough measurements showed that the problems are real, and in our case would have killed our chances of meeting performance targets had we not found them and dealt with them.

    Some bigger issues for server-side design: be careful how you use remote calls (such as RMI) and how you use persistence (such as JDO). But the small things, which the article seems to misrepresent, matter too.
  • Re:Java is Slow (Score:2, Informative)

    by CognitivelyDistorted ( 669160 ) on Sunday May 18, 2003 @12:33AM (#5984027)
    Java isn't slow. Java programs are slow.

    If you wrote a program with mostly static methods, primitive types, and arrays, minimizing object creation and virtual method calls, it would run almost as fast as the equivalent C++ program. A couple years back, I implemented Sieve of Eratosthenes in C++, Java, and VB, and the speeds were comparable. IIRC, on Windows they were within 10% of each other. On Solaris, bizarrely, C++ kicked Java's ass, but Java was still only about 50% slower.

    But if you write an object-oriented program, it will be slower. OOP tends to be higher-level, and thus faster to write but slower to run. All those memory allocations and virtual method calls take time, and they're difficult to optimize. Also, the standard libraries are kind of slow, because they try to be really general (e.g., synchronized collections).

  • Re:Java is slow (Score:5, Informative)

    by WolfWithoutAClause ( 162946 ) on Sunday May 18, 2003 @12:38AM (#5984054) Homepage
    Let's put it this way:

    I've used Java on embedded applications, on systems that create lots, and lots of objects. And I don't recall ever running out of memory, if there wasn't a bug in the Java program.

    But I'm not saying you're lying or wrong, only that a well tuned, well supported, JVM doesn't do this.

    the opportunistic garbage collection of C/C++ simply leads to better performance than any language that tries to do the garbage collection for you.

    What opportunistic garbage collection of C/C++? You mean delete and free? Get real! Personally, I wouldn't trust the average programmer to even collect garbage correctly more than half the time, and that doesn't cut it. I've had way, way less problems with Java GC than I've ever had with C/C++ in a realtime system. People have spent weeks finding memory leaks; and one time a leak I found was a ghastly C++ compiler bug where the compiler screwed up the automatic destructors on unnamed objects.

  • Re:Times change (Score:5, Informative)

    by j3110 ( 193209 ) <samterrellNO@SPAMgmail.com> on Sunday May 18, 2003 @12:39AM (#5984055) Homepage
    Actually... on that page it says that there is a P133 that can run it at 800x600x64K colors at 12fps with only 32Meg of ram on NT4. This is the bare minimum requirements of memory on NT4 I think. The original doom ran at 320x200 at about 25fps on my 486dx4 120 with 16M of ram. If you ask me, I think this Java version may run faster than the original doom.

    Besides, modern day games use very little CPU compared to 3d accelleration on the card. You can get cross-platform games very easy with GL4Java. (A JNI binding to OpenGL that works on any operating system with OpenGL libraries.) I've seen games written this way that are very snappy, and run well under both linux and windows. I haven't tested them on Mac, but I'm sure they are fine there too.

    If I were to write a game, Java would by my language of choice. Java's NIO networking architecture is quite brilliant. You wouldn't have to port the game to anything. It might take some work getting a JVM on a PS2 with OpenGL libraries, but If you can get linux running, I don't see how getting a VM on it could be so difficult.

    Also, it would be neat if you could use the same CD to play the game on your PS2 as you did to play it on a PC. I'm sure such a game would have more appeal to the masses, not to mention saving lots of money on distributing the game. Runs on Linux, Windows, Mac, PS2, and XBox and will be multiplayer between each one of them. Get out your PC and play against your friend on the XBox.

    I think Java will very soon show the mindless idiots that flame away on slashdot every day about how Java is slow that it really isn't slow any more. Sure there are still a few performance bottle-necks, but on the whole, Java is fast now, especially when compared to the future alternative of .Net. I played a demo game from MS for .Net once. It was an overhead 2d game, and it was so sticky that I couldn't play it.
  • by pHDNgell ( 410691 ) on Sunday May 18, 2003 @01:10AM (#5984187)
    Yes, if I need speed, I use C, the same as anyone else.

    Not me. There are some *fast* functional programming language compilers out there. I've ported some of my log processors from python to OCaml, scheme (for the bigloo compiler) and C. The OCaml and bigloo compiled versions were almost exactly the same speed, and only slightly slower than the C version. The C version took me a *LOT* longer to write due to the difficulty of expressing what I was trying to do in C and making sure it was doing it safely.

    In general, I agree with you, but I make great efforts to avoid C, as I am one of those who believe that C is inappropriate for almost every task for which it's used today (even some of the ones for which I'm using it).
  • Re:Java vs. RAM (Score:3, Informative)

    by Anonymous Coward on Sunday May 18, 2003 @01:13AM (#5984201)
    Umm... No. I read about this too. I haven't been able to dig up the old article and I don't remember if it is part of Apple's 1.4 (which was released well after Sun's 1.4, and thus not there), or continuing under Apple development. It isn't in Sun's releases, and maybe not in any other public release (I haven't noticed improvements on my PowerBook).
    Apple has indeed implemented shared memory for system class generation [apple.com] (since 1.3 in fact), but it has yet to be backported to a Solaris/Wintel/Linux official release.

    Some more info available here: http://java.sun.com/features/2002/03/mac.osx.html [sun.com]

  • by Markus Registrada ( 642224 ) on Sunday May 18, 2003 @01:22AM (#5984225)
    Java has always been naturally slow. Like all traditionally slow languages, heroic measures have been taken to attack the problems, and most of the bottlenecks have been looked into. Bytecodes get compiled to native code, garbage-collectors get increasingly clever. Still the programs are way too slow. Why?

    One of the reasons is that interactions with caches are hard to model, making it hard to know what to do to minimize problems. Caching is, inherently, a deal with the devil: you get speed but lose understanding. Sometimes you lose the speed too. Even when you understand, there's not much you can do. Sometimes complicated stuff is inherently expensive.

    When I say caching, I mean not just CPU caches of RAM, but also RAM caches of (potentially swapped-out) process space. If you allow a naive garbage-collector to operate freely, it will happily consume the entire address space available, typically the sum of available RAM and swap space, before garbage-collecting, so the process will run not from RAM but from swap. When it garbage-collects, too, it has to walk a lot of that memory, and swap it all in.

    Just running "ulimit -d" in the shell where the java (or other GC-language) program runs can help a lot. It will GC a lot more often, but if nothing is swapped out, the GC happens a lot faster, and the program's regular execution doesn't have to touch swapped-out pages. You have to know a lot about the program and the data it uses to guess the right ulimit value, and if you guess wrong the program fails, but a thousand-fold speed improvement earns a lot of forgiveness.

    Did you really believe garbage collection would mean you don't have to know about memory management? It makes memory management harder, because the problem remains but there's less you can do about it. (For trivial programs it doesn't matter. If you only write trivial programs, though, you might as well find some other job.)

    There's a similar effect with the CPU cache and RAM. Ideally you want the program code and the data it operates on all to live in cache, because touching the RAM takes 100 times as long at touching cache. With bytecodes, you have a lot more "cache pressure" -- you have the bytecodes themselves, the just-in-time compiler, and the native code it generates. At the same time, since your memory manager generally can't re-use memory that you just freed, it allocates other memory that, when touched, pushes out something else that was useful (such as program code).

    The result is that no matter how clever the JVM is, there's not much it can do to get the performance of real programs close to optimal, or even within a pleasing fraction of equivalent C++ code. This despite all the toy benchmarks that seem to prove otherwise, and which carefully avoid all these real-world problems.

    Of all the promised features of Java (like Lisp before it and C# after it), we're left with the sole remaining feature, that its virtual machine specifies precisely (or abstracts away) enough details of the runtime environment that the code is more portable than a faster native implementation, and the code might get written faster for the author having avoided thinking about details that affect performance.

    The sole saving grace is that most programs don't have much need to run very fast anyway, or if they do it's hard to prove that they ought to run faster. Most people take what they get without complaining, or without complaining to anybody who cares, or without doing anything to make whoever is responsible uncomfortable enough to have to do anything differently. A whole generation trained to accept programs that crash daily or hourly is thrilled to find a program whose biggest problem is that they suspect it might be sluggish.

  • by mgrant ( 96571 ) on Sunday May 18, 2003 @01:25AM (#5984239) Homepage

    You can avoid a lot of these problems in many cases if you use a function like "select()" in a single-threaded program (which, IIRC, Java unfortunately doesn't support).

    The standard java NIO APIs [sun.com] support non-blocking IO (which is what select() is).

  • Re:Java vs. RAM (Score:4, Informative)

    by kwerle ( 39371 ) <kurt@CircleW.org> on Sunday May 18, 2003 @01:43AM (#5984288) Homepage Journal
    OK. I've been called on the carpet, so it's time to get my facts straight:

    From http://www.apple.com/java/ [apple.com]
    Apple developed an innovative new technology that allows Java code to be shared across multiple applications. This reduces the amount of memory that Java applications normally use. And it fits right into Sun?s Hot Spot VM, allowing Mac OS X to remain compatible with standard Java. In addition, Apple has given this implementation to Sun so the company can deploy it on other platforms. Just one example of how Apple supports standards and shares ideas to benefit all.

    You're right in that I can't find any evidence that SUN has rolled this. My hope would still be that this is will be Java Myth of the future. For now it just sucks not to be an Apple user.

    I don't know about Anm's experience on his PB...
  • by leomekenkamp ( 566309 ) on Sunday May 18, 2003 @03:06AM (#5984461)

    Java Objects tend to be pretty heavy, partly because every Object carries a virtual table (to implement polymorphism, reflection, etc.) (...)

    Maybe this is how urban myths come into life?

    An object in java does not have a 'virtual table'; a class has a table with method pointers, an instance of that class does not. One could say that "the method table is static". It would be very foolish to have x exact copies of a method table for x instances of the same class.

  • by johannesg ( 664142 ) on Sunday May 18, 2003 @06:13AM (#5984789)
    Actually that easy magic _does_ exist: it's the profiler. I don't know if Java has a profiler, but if it has you should find out how to use it because it is incredibly useful for identifying that small portion that needs more attention (*).

    To support this with some real numbers, a while ago I was profiling a C++ application I was writing. The application has ~200,000 lines of code, and was writing out ~3,000 values per second. This was not good enough, so I profiled, and carefully improved the "top scorers" in the profile. By changing ~200 lines (spread over a variety of classes and functions) I managed to bring the speed up to ~55,000 values per second. So that's 0.1% of the lines, and an 18 times increase in performance. That's not a bad result for one afternoon of careful coding.

    Were those 200 lines so badly written in the first place? Hell, no. They were fine. But there was a potential for improvement here, and making that improvement had a discernible effect throughout the system. I could spend the rest of my life improving the rest in the same manner, but I doubt I could get another factor two out of them.

    It goes without saying that without the profiler I could never have done this.

    For the record, I found that there were repeated calls to strlen() in a tight inner loop. The most important thing I did was eliminating that call. Smarter buffer management did the rest. The biggest remaining bottleneck is actually in sprintf (%f) - the conversion from float to string is comparatively slow. Just generating all the values without doing that conversion gets me a speed of around 180,000 values per second.

    (*) And if it hasn't, do yourself a favor and get a real development environment. Please.

  • Re:Java is Slow (Score:2, Informative)

    by Jonner ( 189691 ) on Sunday May 18, 2003 @07:10AM (#5984876)
    The slow startup time of typical JVM's does make it feel slow and is a major annoyance. I believe at least part of the problem is that Java was originally designed to be used in a standalone enviornment instead of running on top of a general purpose operating system like *nix or Windows. When the JVM only starts once every few hours, startup time doesn't matter much. Echidna [javagroup.org] is an attempt to avoid the memory bloat and startup time of many JVM processes. I haven't tried it yet, but I probably will if I do much more with Java.

    More generally, any language or runtime environment that is significantly different from that of the operating system is at a disadvantage. I wonder if any high level, dynamic, or interpreted language might benefit from a server or memory manager for the shared parts of the runtime, instead of each program having its own, independent runtime.
  • by smcv ( 529383 ) on Sunday May 18, 2003 @07:38AM (#5984915) Homepage

    Unreal, Unreal Tourmanent, Unreal 2 and UT2003 (as well as the numerous games using their engine - Deus Ex, Rune and so on) are mostly written in Unrealscript, an object-oriented language heavily inspired by Java.

    Epic didn't use Java itself, although Tim Sweeney did consider it:

    During the early development of UnrealScript, several major different programming paradigms were explored and discarded before arriving at the current incarnation. First, I researched using the Sun and Microsoft Java VM's for Windows as the basis of Unreal's scripting language. It turned out that Java offered no programming benefits over C/C++ in the Unreal context, added frustraging restrictions due to the lack of needed language features (such as operator overloading), and turned out to be unfathomably slow due to both the overhead of the VM task switch and the inefficiencies of the Java garbage collector in the case of a large object graph. Second, I based an early implementation of UnrealScript on a Visual Basic variant, which worked fine, but was less friendly to programmers accustomed to C/C++. The final decision to base UnrealScript on a C++/Java variant was based on the desire to map game-specific concepts onto the language definition itself, and the need for speed and familiarity. This turned out to be a good decision, as it has greatly simplified many aspects of the Unreal codebase.

    --Tim Sweeney, Unrealscript Language Reference [epicgames.com]

    As well as all the Java-ish goodies, UScript has simple syntax for game stuff - network replication, client/server code, stateful objects, vectors, portable package files, savegames, and so on. Its memory management is deliberately a bit slow - it seems Java is optimized for few objects which get created and destroyed rapidly, while UScript works well with many objects as long as you don't create or destroy them too often.

    To make the game run fast enough, it *still* needs to delegate the "grunt work" to native C++ code - as well as graphics, physics and sound code are done natively for speed (Unrealscript functions are only called when something "interesting" happens, like a collision, or an animation finishing).

    UnrealScript is a slow language compared to C/C++. A typical C++ program runs at about 50 million base language instructions per second, while UnrealScript runs at about 2.5 million - a 20X performance hit. The programming philosophy behind all of our own script writing is this: Write scripts that are almost always idle. In other words, use UnrealScript only to handle the "interesting" events that you want to customize, not the rote tasks, like basic movement, which Unreal's physics code can handle for you. For example, when writing a projectile script, you typically write a HitWall(), Bounce(), and Touch() function describing what to do when key events happen. Thus 95% of the time, your projectile script isn't executing any code, and is just waiting for the physics code to notify it of an event. This is inherently very efficient. In our typical level, even though UnrealScript is comparably much slower than C++, UnrealScript execution time averages 5-10% of CPU time.

    The Unreal engine has been ported to at least Windows/x86, MacOS Classic/PPC, Linux/x86, Playstation 2 and X-Box. The binaries that need porting are small (the complete UT binaries/patches package for Linux, which enable you to install the latest release Linux UT from the original Windows UT CD-ROM, is comparable in size to the latest update patch for the Windows version).

    The rest of the game files (scripting, models, textures, music, etc.) and the vast majority of UT modifications (including the official Bonus Packs) will work on Windows, Linux and MacOS with no effort (and they'd probably work on the consoles if there was some way to install them). There have been a couple of Windows-only mods, but these are ones which need OS access UScript won't give them (like the demo frontend UDemoManager) or need lower-level access to the game code (like the MP3 player in Godz, or dynamically creating new textures in RealTournament).

  • by james_bray ( 188143 ) * on Sunday May 18, 2003 @08:15AM (#5984977) Homepage
    I know this is just feeding the trolls, but I couldnt resist:

    "Trying to run java applications over X at long distances makes me want to commit suicide."

    There used to be a problem with running Java on a remote X server with JDK 1.2 and 1.3, but it is fixed now in 1.4.

    "Then there is the damn JVM's that each app needs..."

    The new Isolation API [jcp.org] slated for 1.5 should hopefully sort out the JVM-per-app isssue (I agree it's crap).

    "For some reason the screen flickers every time you run a java app"

    Again, fixed in 1.4 AFAIK.

    "Humm, and cut/paste sucks, yes you can use key combos, but sometimes in windows, its nice to select all, and copy."

    No quite sure what you mean here. If you mean in "Windows" (not windows) then you can select all and copy (CTRL+A & CTRL+C) in any Java text widget).

    "If you cant have command line, and you must have a GUI, for gods sake use a HTML."

    What??? I assume you are talking about web-based applications here? I agree, that for web applications, HTML is *usually* the way to go. However, there are some very nice standalone Java applications out there. For example (and this is not a plug, just an example), one of the best GUI CVS clients I have found is a Java application (SmartCVS).

    Just my 0.02c. I've been developing Java applications for the last 7 years (since 1.1), so I think I'm entitled to an opinion....

    James Bray
  • Re:Times change (Score:3, Informative)

    by Yarn ( 75 ) on Sunday May 18, 2003 @08:57AM (#5985054) Homepage
    He wasn't going to use it for the renderer, but for the AI/physics etc which was QuakeC bytecode in Quake 1, DLL/.so in Quake 2 (& Q3a IIRC)
  • Re:Java is slow (Score:2, Informative)

    by mallorean ( 410993 ) on Sunday May 18, 2003 @11:08AM (#5985468)
    Did anyone try running the obvious test....
    public class RunLoop
    {
    public static void main( String[] args )
    {
    while ( true )
    {
    Object o = new Object();
    o = null;
    }
    }
    }
    You can run this till the cows come home and you won't run out of memory. Running the JVM with 64MB and -verbosegc
    ....
    [GC 606K->94K(1984K), 0.0004234 secs]
    .... quizillion times....
    [GC 606K->94K(1984K), 0.0004110 secs]
    ....
    As you can see:
    1. The VM does free memory in "real-time" ( whatever that may mean )
    2. The amortized amount of memory is zero ( it keeps falling back to the base 94K used for the base java classes.
    If you realy want to know how the VMs memory works and how to tune it, you could do worse than read the Hotspot GC Notes [sun.com]. Agreed that Java is not the greatest language there could be, but it is the best mainstream language for a majority of applications. BTW, this test was done on a rather obsolete PIII
    Memory: 127544k/130944k available (1008k kernel code, 412k reserved, 1636k data, 64k init)
    DENTRY hash table entries: 262144 (order: 9, 2097152 bytes)
    Buffer-cache hash table entries: 131072 (order: 7, 524288 bytes)
    Page-cache hash table entries: 32768 (order: 5, 131072 bytes)
    VFS: Diskquotas version dquot_6.4.0 initialized
    CPU: Intel Pentium III (Katmai) stepping 03
  • by knubo ( 615210 ) on Sunday May 18, 2003 @12:06PM (#5985733) Homepage
    Everyone writing Java, where the heap size goes ballistic (huge J2EE applications), should really read the "Tuning Garbage Collection" article written by Sun:

    http://java.sun.com/docs/hotspot/gc/ [sun.com]

    Normally you would have an idea how the memory footprint of your J2EE application would be. Do you have long lived objects, or short lived objects? Do you create a lot of new objects in your code? Are there big static tree-structures? Tuning with this in mind could be what makes your application run at all or not at all when the load comes.

    In particular is it a good idea to configure the garbage collector so long lived objects are seldom attempted garbage collected, while new temporary objects are cleaned away so that the allocated memory area are fast freed. Your goal should be that the system should never really need to do full GC.

    One example of this is long startup time due to several full GC in the process. Solution - configure your system to start with sufficient memory from the start. Your system shouldn't be needing to hit full GC without managing to free enough memory.

    If you have a J2EE application with EJBs and stuff - make sure that the OLD region is big enough to keep all the pooled objects, and that the number of young survivor spaces are many enough that you don't move "use and throw" objects into the old region.

    Thinking in these lines you might be able to make your server applications only perform full GC when the system "feels that it needs to", and not when it must. (For instance at the timed intervals due to GC in relation with RMI).

    A sideeffect of optimizing like this is that one needent worry about creating new objects - allocating a new object only takes a couple of cycles of memory management (moves the free pointer), and if you configure the GC to wipe such objects using the incremental GC (fast!) then memory management shouldn't become a bottleneck. (Not counting in the actual initialization process - if it is costly, reusing objects would probably be a good idea...)

    KEB

  • by kinga ( 1655 ) on Sunday May 18, 2003 @04:01PM (#5987076)
    the double-checked-locking pattern is thread-safe

    Bullshit.

    The "Double-Checked Locking is Broken" Declaration [umd.edu].

    It has a lengthy explanation of why it is broken in Java (because of possible reordering) and also a proposal for fixing the problem. Also see Bill's paper [umd.edu], in which he tells of discussions he had with Guy Steele (as in Gosling, Joy and Steele, The Java Language Specification).
  • by edlong ( 457259 ) on Sunday May 18, 2003 @04:24PM (#5987236)
    Perhaps the experts can comment on this one, but isn't one correct way to implement the thread-safe singleton example in the article as such:

    class SomeClass {
    private Resource resource = null;

    public synchronized Resource getResource() {
    if (resource == null)
    resource = new Resource();
    return resource;
    }
    }

    On immutable objects (string vs. stringBuffer)

    SUN itself claims that using StringBuffer is faster (e.g.
    http://developer.java.sun.com/developer/Tec hTips/1 998/tt0120.html). These 'benchmarks' are like that 'chart makers' that give you x and y percentages just to make their case look good. And in most instances, it's a specific situation that is being dealt with, which could be such a minutia element, but makes for a good razzle.
  • by Anonymous Coward on Sunday May 18, 2003 @05:19PM (#5987601)
    Lisp is a great language, but it is not simple to program -- especially if you want adequate performance. If you haven't already read it, I recommend Richard Gabriel's "Patterns of Software" -- great book, and more than a little on Lisp.
  • by alext ( 29323 ) on Sunday May 18, 2003 @06:08PM (#5987907)
    I hope that the above post is part of an elaborate joke. Otherwise, looking at this and the 455 other messages comprising the debate so far, I don't think /. is about to improve its its position in the 'where to come for Java enlightenment' stakes.

    1) Re: swapping. Java memory management will always be superior to that of the OS - OS constraints should never be greater than those applied by the VM. The memory limit of a Java process is defined with the -Xmx=nnn parameter. For production use, this should never be more than the physical memory actually available to the Java process.

    2) Re: CPU cache: By the time a CPU executes compiled code, bytecodes are nowhere near the CPU cache (they were never near the instruction cache). The fact that the code was earlier produced from bytecodes is completely irrelevant. Furthermore, bytecode compilation is persistent - compiled code is never destroyed for memory management purposes.

    3) Java and C++ optimizations: by definition, a Java JIT compiler can make all the optimizations a static compiler can make, and then some. This is because: a) the bytecode is the semantic equivalent of the source, so all source optimizations can be applied; b) it additionally has access to the complete code base, not just the equivalent of a single source file and c) it has access to the dynamic characteristics of a program, such as "branch taken" metrics, meaning that potentially indefinite refinements of the program structure are possible.

    For those that are true seekers after knowledge, I think it is safe to say that your reading time will be better spent with Sun's papers on GC or VM design, starting here [sun.com], and perhaps comparing mechanisms with those of LISP machines, Dotnet or the Parrot VM.

    I also recommend getting up to speed with the new I/O, printing and regexp features found in 1.4 - a good start is Travis's JDK 1.4 tutorial, though it does not cover everything new.
    .
  • final methods (Score:3, Informative)

    by cmburns69 ( 169686 ) on Sunday May 18, 2003 @06:24PM (#5987994) Homepage Journal
    I tested out what he says about final methods and to my surprise, I found that the final methods were consistantly slower.

    An online Starcraft RPG? Only at [netnexus.com]
    In Soviet Russia, all your us are belong to base!
    Karma: redundant

    Here are the results I found, the code is below:

    First test, method1 is not final
    Running method1() TIME: 4577
    Running method2() TIME: 4596
    Running method2() TIME: 4637
    Running method1() TIME: 4547
    Running method1() TIME: 4547
    Running method2() TIME: 4566
    public static void method1() AVERAGE: 4557
    public static final void method2() AVERAGE: 4599.66

    Second test, method1 is now final
    Running method1() TIME: 4557
    Running method2() TIME: 4576
    Running method2() TIME: 4537
    Running method1() TIME: 4597
    Running method1() TIME: 4636
    Running method2() TIME: 4557
    public static final void method1() AVERAGE: 4596.66
    public static void method1() AVERAGE: 4556.66

    Here is the code I used. Its ugly, but I did it the way I did to best mitigate the effects of the JVM optimizing the code:
    package benchmarks;

    public class FinalTest {

    public static int INC;
    public static final void method1() { INC++; }
    public static void method2() { INC++; }
    public final static int TEST = 1000000000;
    public static void main(String[] args) {
    long start;
    INC = 0;
    start = System.currentTimeMillis();
    System.out.println("Running method1()");
    for(int i=0; i<TEST; i++) method1();
    System.out.println("TIME: "+(System.currentTimeMillis()-start));

    INC = 0;
    start = System.currentTimeMillis();
    System.out.println("Running method2()");
    for(int i=0; i<TEST; i++) method2();
    System.out.println("TIME: "+(System.currentTimeMillis()-start));

    INC = 0;
    start = System.currentTimeMillis();
    System.out.println("Running method2()");
    for(int i=0; i<TEST; i++) method2();
    System.out.println("TIME: "+(System.currentTimeMillis()-start));

    INC = 0;
    start = System.currentTimeMillis();
    System.out.println("Running method1()");
    for(int i=0; i<TEST; i++) method1();
    System.out.println("TIME: "+(System.currentTimeMillis()-start));

    INC = 0;
    start = System.currentTimeMillis();
    System.out.println("Running method1()");
    for(int i=0; i<TEST; i++) method1();
    System.out.println("TIME: "+(System.currentTimeMillis()-start));

    INC = 0;
    start = System.currentTimeMillis();
    System.out.println("Running method2()");
    for(int i=0; i<TEST; i++) method2();
    System.out.println("TIME: "+(System.currentTimeMillis()-start));

    }
    }
  • by Friendless ( 33557 ) on Sunday May 18, 2003 @07:28PM (#5988330)
    Java has some brilliant profilers. JProbe is the one I use, but I hear that OptimizeIt is good as well.
  • by Anonymous Coward on Tuesday May 20, 2003 @07:33AM (#5997573)

The one day you'd sell your soul for something, souls are a glut.

Working...