Let me start off with the standard disclaimers: I have written a number of large multi-threaded Swing and SWT apps. I don't use either exclusively though I prefer SWT primarily because of the fonts, native LAF, and native integration (e.g. ActiveX).
I am sure this is true, but the statement is not particularly relevant unless we have some estimate of "how much".
So, to provide a little data for group to discuss, I wrote HelloSwing, and HelloSwt. Each has a button and a text box. I put a breakpoint in the button handler of each and upon debugging, had a look at the call stacks. Here is what I found...
First, let's point out that the SWT call stack does not include the native calls that map a mouse click to a specific button handler, which seem to account for 3 calls in the Swing stack (the LightweightDispatcher calls).
Now, back to my original question... Can somebody out there give me a
rough numerical estimate
(percentage), based on their experience, of how much optimization (via inlining, etc) a good JIT compiler will make on such call stacks?
Other Notes:
- I used JDK 5.0.
- The call stacks for a menu selection are similar: 29 for Swing and 9 for SWT.
You are missing the story on scalability. Method call overhead in Java is dwarfed by JNI. Multiply this by a decent number of components in a form, and suddenly long stack trace does not matter (if it ever did). I like "table with 500,000,000 rows" example more
You'll remember my reply to the 500,000,000 row table example included SWT's solution which (as long as the user doesn't slowly scroll down the entire length of the table) is probably more efficient resource wise than Swing's table models (all factors included). No one is denying that Swing handles data better, but as the stack traces show, it has quite a bit more overhead in other areas.
I've heard quite a number of claims about JNI calls being terribly expensive. Does anyone have benchmarks to back this up?
JNI performance has increased a lot in recent releases. I benchmarked this long ago and checked again: In JDK 5.0, with HotSpot Client (the choice for desktop apps), a common (polymorphic) method invocation has a overhead of ~20ns in my machine, while an equivalent JNI call is -25ns. These numbers are for a simple method ("int f (int)"), but while more complex method signatures should increase the relative overhead of JNI, I don't think that's going to make a big difference. Remember that libraries that depend on native code, if properly implemented (as I guess both Swing/AWT and SWT are), will go through great pains to reduce the granularity of native invocations and callbacks, with optimizations such as buffering operations or resorting to NIO and volatile images where appropriate.
The major impact of JNI is that the JIT compiler cannot inline across the JNI frontier. But then, the argument is reduced to the inlining issue.
Now, deep stacks are certainly a nightmare for an inliner. The JIT compiler will not inline a dozen layers of method calls, not even if each of these methods is an one-liner like delegation code; not even if all such methods can be devirtualized.
Another problem is that you have nore code running in the Swing case than in the SWT case. Roughly speaking, the more code, the slower your app, all else (JIT optimizations or JNI) being equal. I don't think that SWT is simply packing more code per method so it executes a similar number of statements per event (or other operation). It's not a difference of architecture, like if Swing is a refactored version of SWT or SWT is a monolithic version of Swing full of "blob" antipatterns (huge methods). It's a difference of size: Swing is more complex, more flexible, it does more actual work per operation, and it does most things in a more complicated way; in part to provide flexibility and extensibility that SWT lacks, in part because it implements in Java code stuff that SWT doesn't, like widget rendering, D&D, font processing etc. In this last subject, SWT delegates work to the OS, and the native libraries will always beat Java's, not because they are native, but because they are more mature, can more easily rely on HW acceleration, and even dirty tricks like running in kernel mode (the case for Windows).
Finally, a good comparison of these stack traces would consider not inly their depth, but the size of the entire tree of invocations that spreads from a "root" call, like an event handler in the JNI side, or the app invoking a high-level toolkit API in the Java side. But the deeper tree is more likely the bigger one, unless the smaller tree has a very large "spanning" factor. The full trees could be captured in code profilers.
Re: Swing vs. SWT Performance - Have a Look at the Call Stacks
> Can somebody out there give me a rough numerical estimate (percentage), based on their experience, of how much optimization (via inlining, etc) a good JIT compiler will make on such call stacks?
So much that it is a completely useless benchmark. How much exaclty depends on so many things that it is useless to attempt to put numbers on it. Besides, your assumption that this is the reason for the (perceived/imagined?) performance advantage of swt is really flawed and based on a really poor understanding of how the jvm works.
I've never heard a good, wel argued case for any performance advantages of SWT. Most of the arguments boil down to "it's native, QED dude!". Somehow that doesn't convince me. Forget about benchmarks or metrics backing up it is actually faster. From my experience of using swing and swt apps simulatneously, there is no noticable difference. When either type of application feels slow the cause is usually excessive memory usage or poor usage of threads (i.e. trying to do stuff on the rendering thread that end up blocking everything).
You say that method signatures aren't very import for JNI performance testing but everything I've ever read about JNI performace, heard about, or experienced myself indicates the EXACT opposite. Run your tests with some arrays and non-primitive types and let me know how it goes.
Re: Swing vs. SWT Performance - Have a Look at the Call Stacks
On a top end machine running XP, yes, Swing and SWT feel almost identical in performance. Try running your side by side test on a low end machine (think 500 Mhz with 256 RAM) and tell me it feels identical.
I don't have time for another well argued performance post. If you've got an hour or so, check out http://www.javalobby.org/java/forums/t64684.html for some good back and forth on Swing vs SWT performance (especially considering JNI).
While I stated something wrong/obtuse initially (about JNI dwarfing Java method invokations), by the virtue of being vague, it was not far from reality that is: "(JNI invokation + passing in-out parameters) ~ (4 to 7) x (pure Java invokation + passing in-out parameters)"
Or so I read benchmark referred by Mark
Re-ran using JDK 1.5.0_06 on Linux:
Simulator> java -Djava.library.path=. -server Simulator -n 20
Expect results in 100 seconds
Throughput in rows per second (bigger is better)
JavaRowConsumer 551997
FineGrainedJNIRowConsumer 79067
CoarseGrainedJNIRowConsumer 74034
BytePackedJNIRowConsumer 115234
SocketRowConsumer 93944
Simulator> java -Djava.library.path=. -client Simulator -n 20
Expect results in 100 seconds
Throughput in rows per second (bigger is better)
JavaRowConsumer 373374
FineGrainedJNIRowConsumer 79254
CoarseGrainedJNIRowConsumer 81999
BytePackedJNIRowConsumer 103016
SocketRowConsumer 88631
Looks like since JDK 1.3 the gap has increased... JNI overhead with parameter passing is 4 to 7 times compared to Java method invokation (which alone has improved, it seems).
> Remember that libraries
> that depend on native code, if properly implemented
> (as I guess both Swing/AWT and SWT are), will go
> through great pains to reduce the granularity of
> native invocations and callbacks
You would think so, but as I understand it, one of the key architecture decisions behind SWT is the exact opposite. All native methods simply marshal their arguments and invoke a single API in the underlying platform. So if some place in the code needs to make five API calls, then that's five calls to five native methods. That means there are five context switches to/from JNI with all the overhead that implies.
It's done that way to minimize the amount of native code required, and allows the developers to use their Java debuggers for nearly everything. But it does seem like it could be detrimental to performance.
J2ME programmers count bytes the way a super-model counts calories.
Read again: I said that complex signatures
should increase
JNI's overhead... but I just don't think that this increase would matter a lot in the overall performance of Swing or SWT. Even if some JNI method is 10X slower than my example, this won't be a large percentual of the time spent in the entire call tree. Of course JNI calls can be even slower, for braindead interfaces passing complex data structures such as arrays of objects, collectiosn etc., or for libs that needs to invoke Java methods from the native side, but I don't think such things will be frequent in GUI toolkits.
Look for example at SWT's "OS" class, e.g. org.eclipse.swt.internal.win32.OS for the Win32 version. It's a huge pack of all native methods used by SWT. You will easily notice that the average signature complexity is pretty small. There's a boatload of methods that only pass primitive types, e.g. "boolean PostMessage(int hWnd, int Msg, int wParam, int lParam)" (which, if you remember your Petzoldian programming, is a hugely useful Win32 API). Then, many methods pass around simple arrays (e.g. Unicode strings are passed as char[] and ASCII strings as byte[]). The most complex methods are those that pass some Java object for functions that will update these objects ("out" parameters for Win32), like the all-important "boolean PeekMessageW(MSG msg, int i, int j, int k, int l)". This is about as complex as the SWT native API goes, and it's not a hugely expensive native call by any stretch of imagination. I didn't look at the natives for SWT/Swing but I don't think it's a much different story.
Re: Swing vs. SWT Performance - Have a Look at the Call Stacks
> On a top end machine running XP, yes, Swing and SWT
> feel almost identical in performance. Try running
> your side by side test on a low end machine (think
> 500 Mhz with 256 RAM) and tell me it feels
> identical.
Well I can just talk about the GTK2-Version of SWT (Linux) and for me Swing based applications perform better on my Duron800. Both are slow compared to native toolkits like QT or Fox-Toolkit. (Native GTK apps are slow too).
On the other side the swtfox port i tried 2 years ago (swt on top of FOX) outperformed both swing and swt/gtk2.
Re: Swing vs. SWT Performance - Have a Look at the Call Stacks
SWTFox is incredibly fast. Strangely enough, it's the one with less JNI calls...
As I've said before, Clemens, I think there's something weird with your X11 config because the performance you've described is so out of the ordinary. As you mentioned, native GTK apps are slow too.
Swing vs. SWT Performance - Have a Look at the Call Stacks
At 1:20 PM on Mar 3, 2006, Stephen Strenn wrote:
Fresh Jobs for Developers Post a job opportunity
I realize these are just forums, but one problem I have with a lot of the discussion out there on the topic of Swing vs. SWT performance is the amount of hand waving on essential topics. With all due respect to the author, here is an example: The difference here is that a good JIT can inline large portions of the Swing code base (such as critical event handler code) all the way into the rendering thread.
I am sure this is true, but the statement is not particularly relevant unless we have some estimate of "how much".
So, to provide a little data for group to discuss, I wrote HelloSwing, and HelloSwt. Each has a button and a text box. I put a breakpoint in the button handler of each and upon debugging, had a look at the call stacks. Here is what I found...
SWING APP:
Thread [AWT-EventQueue-0] (Suspended (breakpoint at line 162 in MainWindow))
MainWindow.btnSayHelloActionPerformed(ActionEvent) line: 162
MainWindow.access$0(MainWindow, ActionEvent) line: 161
MainWindow$1.actionPerformed(ActionEvent) line: 63
JButton(AbstractButton).fireActionPerformed(ActionEvent) line: 1849
AbstractButton$Handler.actionPerformed(ActionEvent) line: 2169
DefaultButtonModel.fireActionPerformed(ActionEvent) line: 420
DefaultButtonModel.setPressed(boolean) line: 258
BasicButtonListener.mouseReleased(MouseEvent) line: 234
JButton(Component).processMouseEvent(MouseEvent) line: 5488
JButton(JComponent).processMouseEvent(MouseEvent) line: 3126
JButton(Component).processEvent(AWTEvent) line: 5253
JButton(Container).processEvent(AWTEvent) line: 1966
JButton(Component).dispatchEventImpl(AWTEvent) line: 3955
JButton(Container).dispatchEventImpl(AWTEvent) line: 2024
JButton(Component).dispatchEvent(AWTEvent) line: 3803
LightweightDispatcher.retargetMouseEvent(Component, int, MouseEvent) line: 4212
LightweightDispatcher.processMouseEvent(MouseEvent) line: 3892
LightweightDispatcher.dispatchEvent(AWTEvent) line: 3822
MainWindow(Container).dispatchEventImpl(AWTEvent) line: 2010
MainWindow(Window).dispatchEventImpl(AWTEvent) line: 1774
MainWindow(Component).dispatchEvent(AWTEvent) line: 3803
EventQueue.dispatchEvent(AWTEvent) line: 463
EventDispatchThread.pumpOneEventForHierarchy(int, Component) line: 242
EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: 163
EventDispatchThread.pumpEvents(int, Conditional) line: 157
EventDispatchThread.pumpEvents(Conditional) line: 149
EventDispatchThread.run() line: 110
SWT APP:
Thread [main] (Suspended (breakpoint at line 155 in MainWindow))
MainWindow.btnSayHelloWidgetSelected(SelectionEvent) line: 155
MainWindow.access$0(MainWindow, SelectionEvent) line: 154
MainWindow$1.widgetSelected(SelectionEvent) line: 61
TypedListener.handleEvent(Event) line: 90
EventTable.sendEvent(Event) line: 66
Button(Widget).sendEvent(Event) line: 843
Display.runDeferredEvents() line: 3080
Display.readAndDispatch() line: 2713
MainWindow.main(String[]) line: 149
Swing: 27 method calls
SWT: 9 method calls
First, let's point out that the SWT call stack does not include the native calls that map a mouse click to a specific button handler, which seem to account for 3 calls in the Swing stack (the LightweightDispatcher calls).
Now, back to my original question... Can somebody out there give me a rough numerical estimate (percentage), based on their experience, of how much optimization (via inlining, etc) a good JIT compiler will make on such call stacks?
Other Notes:
- I used JDK 5.0.
- The call stacks for a menu selection are similar: 29 for Swing and 9 for SWT.
134 replies so far (
Post your own)
One button, huh?
You are missing the story on scalability. Method call overhead in Java is dwarfed by JNI. Multiply this by a decent number of components in a form, and suddenly long stack trace does not matter (if it ever did). I like "table with 500,000,000 rows" example moreRe: One button, huh?
You'll remember my reply to the 500,000,000 row table example included SWT's solution which (as long as the user doesn't slowly scroll down the entire length of the table) is probably more efficient resource wise than Swing's table models (all factors included). No one is denying that Swing handles data better, but as the stack traces show, it has quite a bit more overhead in other areas.I've heard quite a number of claims about JNI calls being terribly expensive. Does anyone have benchmarks to back this up?
ActiveObjects: an Easier Java ORM; Fuse: Resource Injection for Java
Re: One button, huh?
JNI performance has increased a lot in recent releases. I benchmarked this long ago and checked again: In JDK 5.0, with HotSpot Client (the choice for desktop apps), a common (polymorphic) method invocation has a overhead of ~20ns in my machine, while an equivalent JNI call is -25ns. These numbers are for a simple method ("int f (int)"), but while more complex method signatures should increase the relative overhead of JNI, I don't think that's going to make a big difference. Remember that libraries that depend on native code, if properly implemented (as I guess both Swing/AWT and SWT are), will go through great pains to reduce the granularity of native invocations and callbacks, with optimizations such as buffering operations or resorting to NIO and volatile images where appropriate.The major impact of JNI is that the JIT compiler cannot inline across the JNI frontier. But then, the argument is reduced to the inlining issue.
Now, deep stacks are certainly a nightmare for an inliner. The JIT compiler will not inline a dozen layers of method calls, not even if each of these methods is an one-liner like delegation code; not even if all such methods can be devirtualized.
Another problem is that you have nore code running in the Swing case than in the SWT case. Roughly speaking, the more code, the slower your app, all else (JIT optimizations or JNI) being equal. I don't think that SWT is simply packing more code per method so it executes a similar number of statements per event (or other operation). It's not a difference of architecture, like if Swing is a refactored version of SWT or SWT is a monolithic version of Swing full of "blob" antipatterns (huge methods). It's a difference of size: Swing is more complex, more flexible, it does more actual work per operation, and it does most things in a more complicated way; in part to provide flexibility and extensibility that SWT lacks, in part because it implements in Java code stuff that SWT doesn't, like widget rendering, D&D, font processing etc. In this last subject, SWT delegates work to the OS, and the native libraries will always beat Java's, not because they are native, but because they are more mature, can more easily rely on HW acceleration, and even dirty tricks like running in kernel mode (the case for Windows).
Finally, a good comparison of these stack traces would consider not inly their depth, but the size of the entire tree of invocations that spreads from a "root" call, like an event handler in the JNI side, or the app invoking a high-level toolkit API in the Java side. But the deeper tree is more likely the bigger one, unless the smaller tree has a very large "spanning" factor. The full trees could be captured in code profilers.
Re: Swing vs. SWT Performance - Have a Look at the Call Stacks
> Can somebody out there give me a rough numerical estimate (percentage), based on their experience, of how much optimization (via inlining, etc) a good JIT compiler will make on such call stacks?So much that it is a completely useless benchmark. How much exaclty depends on so many things that it is useless to attempt to put numbers on it. Besides, your assumption that this is the reason for the (perceived/imagined?) performance advantage of swt is really flawed and based on a really poor understanding of how the jvm works.
I've never heard a good, wel argued case for any performance advantages of SWT. Most of the arguments boil down to "it's native, QED dude!". Somehow that doesn't convince me. Forget about benchmarks or metrics backing up it is actually faster. From my experience of using swing and swt apps simulatneously, there is no noticable difference. When either type of application feels slow the cause is usually excessive memory usage or poor usage of threads (i.e. trying to do stuff on the rendering thread that end up blocking everything).
Re: One button, huh?
Here's a benchmark I found on the web:http://www.str.com.au/jnibench/
Re: One button, huh?
You say that method signatures aren't very import for JNI performance testing but everything I've ever read about JNI performace, heard about, or experienced myself indicates the EXACT opposite. Run your tests with some arrays and non-primitive types and let me know how it goes.Re: Swing vs. SWT Performance - Have a Look at the Call Stacks
On a top end machine running XP, yes, Swing and SWT feel almost identical in performance. Try running your side by side test on a low end machine (think 500 Mhz with 256 RAM) and tell me it feels identical.I don't have time for another well argued performance post. If you've got an hour or so, check out http://www.javalobby.org/java/forums/t64684.html for some good back and forth on Swing vs SWT performance (especially considering JNI).
ActiveObjects: an Easier Java ORM; Fuse: Resource Injection for Java
Re: One button, huh?
That was way back in 1.3 though. Both JIT and JNI have made huge strides in optimizations since then.ActiveObjects: an Easier Java ORM; Fuse: Resource Injection for Java
Re: One button, huh?
On huge strides: some made 'em, some did notWhile I stated something wrong/obtuse initially (about JNI dwarfing Java method invokations), by the virtue of being vague, it was not far from reality that is: "(JNI invokation + passing in-out parameters) ~ (4 to 7) x (pure Java invokation + passing in-out parameters)"
Or so I read benchmark referred by Mark
Re-ran using JDK 1.5.0_06 on Linux:
Simulator> java -Djava.library.path=. -server Simulator -n 20
Expect results in 100 seconds
Throughput in rows per second (bigger is better)
JavaRowConsumer 551997
FineGrainedJNIRowConsumer 79067
CoarseGrainedJNIRowConsumer 74034
BytePackedJNIRowConsumer 115234
SocketRowConsumer 93944
Simulator> java -Djava.library.path=. -client Simulator -n 20
Expect results in 100 seconds
Throughput in rows per second (bigger is better)
JavaRowConsumer 373374
FineGrainedJNIRowConsumer 79254
CoarseGrainedJNIRowConsumer 81999
BytePackedJNIRowConsumer 103016
SocketRowConsumer 88631
Looks like since JDK 1.3 the gap has increased... JNI overhead with parameter passing is 4 to 7 times compared to Java method invokation (which alone has improved, it seems).
Re: One button, huh?
> Remember that libraries> that depend on native code, if properly implemented
> (as I guess both Swing/AWT and SWT are), will go
> through great pains to reduce the granularity of
> native invocations and callbacks
You would think so, but as I understand it, one of the key architecture decisions behind SWT is the exact opposite. All native methods simply marshal their arguments and invoke a single API in the underlying platform. So if some place in the code needs to make five API calls, then that's five calls to five native methods. That means there are five context switches to/from JNI with all the overhead that implies.
It's done that way to minimize the amount of native code required, and allows the developers to use their Java debuggers for nearly everything. But it does seem like it could be detrimental to performance.
Re: One button, huh?
Read again: I said that complex signatures should increase JNI's overhead... but I just don't think that this increase would matter a lot in the overall performance of Swing or SWT. Even if some JNI method is 10X slower than my example, this won't be a large percentual of the time spent in the entire call tree. Of course JNI calls can be even slower, for braindead interfaces passing complex data structures such as arrays of objects, collectiosn etc., or for libs that needs to invoke Java methods from the native side, but I don't think such things will be frequent in GUI toolkits.Look for example at SWT's "OS" class, e.g. org.eclipse.swt.internal.win32.OS for the Win32 version. It's a huge pack of all native methods used by SWT. You will easily notice that the average signature complexity is pretty small. There's a boatload of methods that only pass primitive types, e.g. "boolean PostMessage(int hWnd, int Msg, int wParam, int lParam)" (which, if you remember your Petzoldian programming, is a hugely useful Win32 API). Then, many methods pass around simple arrays (e.g. Unicode strings are passed as char[] and ASCII strings as byte[]). The most complex methods are those that pass some Java object for functions that will update these objects ("out" parameters for Win32), like the all-important "boolean PeekMessageW(MSG msg, int i, int j, int k, int l)". This is about as complex as the SWT native API goes, and it's not a hugely expensive native call by any stretch of imagination. I didn't look at the natives for SWT/Swing but I don't think it's a much different story.
Re: Swing vs. SWT Performance - Who cares?
Performance doesn't matter as much if it is fast enough.Swing vs SWT should be judge on other things: compatibility, architecture, gut feeling...
Re: Swing vs. SWT Performance - Have a Look at the Call Stacks
> On a top end machine running XP, yes, Swing and SWT> feel almost identical in performance. Try running
> your side by side test on a low end machine (think
> 500 Mhz with 256 RAM) and tell me it feels
> identical.
Well I can just talk about the GTK2-Version of SWT (Linux) and for me Swing based applications perform better on my Duron800. Both are slow compared to native toolkits like QT or Fox-Toolkit. (Native GTK apps are slow too).
On the other side the swtfox port i tried 2 years ago (swt on top of FOX) outperformed both swing and swt/gtk2.
lg Clemens
Re: Swing vs. SWT Performance - Have a Look at the Call Stacks
SWTFox is incredibly fast. Strangely enough, it's the one with less JNI calls...As I've said before, Clemens, I think there's something weird with your X11 config because the performance you've described is so out of the ordinary. As you mentioned, native GTK apps are slow too.
ActiveObjects: an Easier Java ORM; Fuse: Resource Injection for Java