Swing faster than AWT?? ZHUH?

HOLD YOUR HORSES, I haven’t discovered anything yet! Ranting beware.

I have been hacking both AWT and SWING for awhile to get the best performance out at the same time as I learn OpenGL.

My problem initially was that there were too many useless threads going on at the same time along with my rendering thread and they were all unneccessary.

Now Sun seems to have very user friendly way of treating developers: http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html#why
However, I’d really like to be incontrol of the things that I do. To me this is crap news, if Swing is supposed to eventually take over the position of AWT it must be fully customizable and I want to be in control of every single thread running. And yes this means the hidden threads that might phuck up the program. If my program freezes, it is clearly my fault, not suns fault and thats why they should leave as much room for me.

Now, there is tons and metric tons of air inside of swing, we are all aware of that, thats why it is slow and people on slower computers can see delays when they click things. For game programming this is not necessarily so. I admit that the hidden threads make my life 1000% easier, but the problem is that I don’t want to do it the easy way. I want it the fast way.

Now here is the possible sollution:

  • invokeLater(): Requests that some code be executed in the event-dispatching thread. This method returns immediately, without waiting for the code to execute.

    • invokeAndWait(): Acts like invokeLater(), except that this method waits for the code to execute. As a rule, you should use invokeLater() instead of this method.

As you can clearly understand where I’m going with this. As a matter of a fact, I haven’t found any reasonable way to access the inner threads in AWT and assuming that a lot of air could be squeezed out if we could access them this article explains everything better:
http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html

Although things are made easy for us, it doesn’t mean that they are necessarily slow. By accessing the swing thread, this saves us one thread, which can be many milliseconds and it will also save the GC from extra work.

I’m not saying swing is the way to go. I’m saying that swing has potential. If it just gave me greater degree of freedom. http://billharlan.com/pub/papers/Improving_Swing_Performance.html.

Now some people would say that omg all this for just one thread? Well, to me even one thread is enough. When I know that my code potentially runs faster in theory, it is enough for me and isn’t everyone saying that Java is too slow? It is slow, certainly slower than C++, thats why to match we must counter the speed gap.

I know we are still light years away, but every single bit helps. I’m not trusting the Sun to make it faster with those policies. I don’t care if an idiot can make a game if it is slow.

The practical uses for hacking the event thread? In theory, you could create game events, that would be handled among the input events or directed into another thread which is the actualy game thread.

The way I categorize things:

Under the hood threads:
-The engine
–Rendering
–Input
–Media(Sound)

These are currently all different threads, except for the sound. If they could be combined, that would be already 1 thread less.

Game threads
-events in game
-physics
-interaction

-Usually combined into one. Now this is what it should be.

The ideal way to render in games: The engine pumps out as much FPS as it is possible, the game thread and the input thread corresponds with the engine, and handles everything so that it goes maximium 72 fps(or whatever the eye/monitor relationship is). Now if the FPS is over 1000, which I’m having right now with my small OpenGL app, the animation is not good looking. Thats why the animation speed must be limited to 72 fps, at the same time with the input thead. Now one lower end computers, the engine must keep count on the FPS part, since if the FPS goes lower than 72fps, the other threads must be adjusted too, so that the game maintains its playability.

This is certainly better design than having everything set to whatever FPS or the infinite fps loop.

So threads required would be:
1.) The graphics engine thread
-This would adjust the engine speed and everything else

2.) The game thread
-follows the engine thread.and keeps the game playable even on lower end systems.

This would help in 2d, but I’m aiming into the third dimensions, be the API opengl or java3d, that doesn’t matter. To get the most speed out of the APIS we must have as secure base as possible, this means we must have go as lowlevel as possible so that the higherlevel api is able to take the full advatange of the environment.

Now when using Java2D or other java-based API, we don’t have to worry about heavyweight/lightweight relationship since on swing, if done correctly, hardware acceleration is easy to do.

Now if we don’t want the lightweight rendering, what now? I will continue when I find out more.

If you read this, please correct all the mistakes I have made in the concepts. Do you have anything to add, howabout comparsion to AWT?

I have nothing to add in comparing AWT to Swing. I only want to add the question again if anyone has ever tried using SWT for game development? The reason for asking is the same as your point: getting it done quickly. AWT calls native widgets which have always been quicker than Swing and I dont see that changing. But like you said, AWT and Swing both hide handling of the event and display thread from the user. SWT, from my reading, does not have this limitation. Events have to be polled manually like writing a C app. This may make SWT harder to use compared to AWT, but there is probably some serious speed gains.

Hopefully old news to all of you, but beware:

When using invokeLater() or invokeAndWait() if you are creating a temporary object to run a command, make sure you subclass runnable, and not Thread. Subclassing thread will leave all the thread objects you created in the unrun state, so they hang around.

The application I’m working on now had 100’s of calls to invokeLater() with a subclass of Thread and by the end of the day we’d have 10’s of thousands of unrun threads hanging around. Not sure on the performance implications of this.

I only bring it up because some “tutorials” on the web have invokeLater using a subclass of Thread, rather than Runnable!

Er, Kevdog, Thread is a Runnable - I suggest you go and find out what the bug is in your code and change your advice!

And everyone - just forget about using Threads in games, and then you won’t have to ask questions about them :slight_smile:

Cas :slight_smile:

Just one question then. If we really don’t want to use threads in a game, how should we deal with multi-sample sound? Or MP3s? or anything like that?

I believe he is referring to 1 ‘developer’ created thread. It’s true, when you send a sound stream to the sound card, an external thread is going to manage the feeding of the stream into the card, blah blah blah, but just like frame-related problems with multiple threads, you also will have the same problem synchronizing audio to the game if you have mulitple threads telling sounds to fiire at various times. The synchronization overhead is complex to keep it together, it’s better to have 1 thread for render->tick process (AI thinks)->player moves->render loops. At this point, multi-processor systems are a weak argument because I don’ tthink there’s a JVM out there that handles it well, and it’s not really your desktop configuration for a game machine.

-Chris

[quote]Er, Kevdog, Thread is a Runnable - I suggest you go and find out what the bug is in your code and change your advice!

And everyone - just forget about using Threads in games, and then you won’t have to ask questions about them :slight_smile:
[/quote]
:slight_smile:

Yes, but a Runnable is not a Thread. And a Runnable is sufficient. So kevdogs advice is deeply true.

And - please don’t forget about threads in games. One of Javas biggest strengths is it’s awareness of multithreading. Hard to do network programming without! Hard to do on-the-fly resource-loading without! But handle them with care, you are always in danger!

My preminary tests show that I have recieved 7% speed increase in my application(using j3d timer) when taking out one thread and using the invoke later, and I was using runnable.

Princec came out of the closet to say this:
And everyone - just forget about using Threads in games, and then you won’t have to ask questions about them

On the other hand you are developing java games, am I correct? If you don’t use any of the java properties and if you go with lwgl as well, I don’t see any reason to program with java at all sine everything could be done in c++, isn’t that true?

Now the invoke later things are not perhaps the most clean way to handly your code, but I got to thinking this when I was doing it.

Is System timer used somewhere in the thread class? I hope not.

Now I’d like to go what SpongeBob said:
When working with games, you are most likely going to use only the frame, and then do some sort of active rendering on top of it.

Now JFrame is heavyweight and it doesn’t differ much from the Awt window, except that its swing and has some swing properties that you can disable. What I tried to say is that there might not be that much difference in between awt and swing. I’m tired now, I will come back later.

That’s exactly what I always try to point out…
:-*

[quote]My preminary tests show that I have recieved 7% speed increase in my application(using j3d timer) when taking out one thread and using the invoke later, and I was using runnable.
[/quote]
As for streaming media or network traffic Sun has came up with a solution to avoid using threads: NIO. Sun specifically stated that threads were an issue and thus created NIO to solve the problem:

http://www.javaperformancetuning.com/tips/nio.shtml

[quote]I don’t see any reason to program with java at all sine everything could be done in c++, isn’t that true?
[/quote]
LWGL, from my understanding, is an API. Almost all the standard Java API commands call back to a C/C++ equiv. Using these APIs, Java programmers get native capabilities without leaving the ease of the Java language. Yes, you can do everything in C/C++ that you can do in Java. But then again, you can do everything in machine language or assembly that you can do with C/C++. Would you want to?

[quote]Now JFrame is heavyweight and it doesn’t differ much from the Awt window, except that its swing and has some swing properties that you can disable.
[/quote]
JFrame, like all Swing components, are layered. These layers effect speed. Thats why JFrames are slower then AWT Frames. And from my understanding of JFrame, the extra Swing stuffing cannot be disabled either.

Eeeeh, always ready to throw the baby out with the bathwater! Bloody engineers and their binary world views eh?

I use most of Java’s most useful features, and don’t use the wrong ones at the wrong times. I use Java because it’s easier than C++, I write code faster, and I find bugs in it faster, and that’s the only reasons, really. But they seem like the best ones.

Cas :slight_smile:

I understand what you mean, but you can set the repaint off, and just add to the content pane, or even use the window itself. Thats what I do. I disabled the passive rendering on the frame, and then added my opengl canvas on top of it and it works great. However, my knowledge stops here. This means that I might be completely wrong, but 7% performance boost seems reasonable to me.

That works but what would the point be. You have just turned a Swing JFrame into the equiv of a Java AWT Frame without the ability to display swing components or use its own graphical context. At that point, wouldnt it just be as easy to use the AWT Frame?

Can you submit a code example of this modified Swing JFrame?

Yes when I’m sure that it is swing and not some other thing. I will PM you when it is on the source code section.

I didn’t quite understand how you can replace threads in games with NIO. Could you direct me to any decent source where this would be done?

RE: replacing threads using NIO.

Disclaimer: I am going on my experience with using select sets in my old unix days of programming and also my experience using sockets in Java, but here goes:

In networked games, you’ll have many clients connecting to a server. In Java (before NIO), for each client there would be a thread that would block on a socket, so 6 clients would consume 6 threads on the server.

Enter NIO: With NIO, you have the concept of selectors and channels. You can have all the client connections set up as channels in a selector, and the selector will tell you which sockets have input ready to be read. So, your NIO game architecture has 2 threads: one that listens for connections and puts new connections into a channel, and the main game thread that does everything else. The game loop would look like this:

Render->AI Thinks->Process user input (read any available input from clients)->Render (loop)

Hence, threads are eliminated using NIO.

-Chris

OK I got it, I found example JCanyon or whatever and it is doing bunch of the same stuff that I’m doing also. Perhaps I shall investigate that closer, but boy is the code hard to read.

Yep, a Thread is a Runnable, but a Runnable is not a Thread :slight_smile: Thread has a lot more overhead.

Note: You wouldn’t do this in a render loop anyway because of the object creation…

On the web I found references to code like:
Thread t = new Thread() {
public void run() {
// do something
}
};

SwingUtilities.invokeLater(t);

This leaves an unread thread hanging around, even after the “do something” code has executed because you never run start() on the thread.

Doing the same thing but with Runnable doesn’t have that problem.

Hm, AIUI a Thread creates no native peer until it is start()ed, and in either case, should be garbage collected just like a Runnable. (I’d be using a Runnable myself but there’s no real harm in using a Thread for this if that’s what you happen to have lying around, is what I’m saying, but I concede)

Cas :slight_smile:

A Thread is not garbage collected until it has been started. But invokeLater doesn’t start the thread, it only executes what is in the run() method. So the thread is left in the unrun state, even though the run() method has been executed, so therefore it is never garbage collected.

Try it in a profiler, you’ll see the Thread hanging around forever. I’m really not sure what effect 10’s of thousands of unrun threads has on performance, but I’m sure it’s still not a good thing :slight_smile: