Bug 51693 - String drawing/measuring bench
Summary: String drawing/measuring bench
Status: CLOSED WORKSFORME
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.0   Edit
Hardware: PC All
: P3 normal with 5 votes (vote)
Target Milestone: ---   Edit
Assignee: Silenio Quarti CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 4585 4615 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-02-11 12:57 EST by Silenio Quarti CLA
Modified: 2019-10-10 16:54 EDT (History)
26 users (show)

See Also:


Attachments
V3 of the Java/C benchmark (10.44 KB, application/octet-stream)
2004-02-26 16:42 EST, Aaron Digulla CLA
no flags Details
StyledText benchmark (3.06 KB, application/octet-stream)
2004-03-02 16:18 EST, Aaron Digulla CLA
no flags Details
Patch against M07 SWT source (2.71 KB, patch)
2004-03-03 16:06 EST, Aaron Digulla CLA
no flags Details | Diff
Felipe's benchmark (8.45 KB, text/plain)
2004-03-04 12:21 EST, Felipe Heidrich CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Silenio Quarti CLA 2004-02-11 12:57:25 EST
This is a bench mark for string drawing and measuring. I will run it on 
different platforms and add the result here.

import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;


public class StringBench {
	
static final int COUNT = 100000;
	
static void test(String msg, GC gc) {
	long time;
	String s1 = "Hello", s2 = "There";
	time = -System.currentTimeMillis();
	for (int i=0; i<COUNT; i++) {
		gc.drawString(s1, 10, 50, true);
		gc.drawString(s2, 10, 150, true);
	}
	System.out.println (msg + " drawString() - count=" + COUNT + " time=" 
+ (System.currentTimeMillis() + time) + " ms");
	time = -System.currentTimeMillis();
	for (int i=0; i<COUNT; i++) {
		gc.stringExtent(s1);
		gc.stringExtent(s2);
	}
	System.out.println (msg + " stringExtent() - count=" + COUNT + " 
time=" + (System.currentTimeMillis() + time) + " ms");
}

public static void main (String [] args) {
	Display display = new Display ();
	Shell shell = new Shell (display);
	shell.setSize(500, 500);
	shell.open ();
	GC gc = new GC (shell);
	test("Control", gc);
	gc.dispose ();
	Image image = new Image(display, 500, 500);
	gc = new GC(image);
	test("Image", gc);
	gc.dispose();
	image.dispose();
//	while (!shell.isDisposed ()) {
//		if (!display.readAndDispatch ()) display.sleep ();
//	}
	display.dispose ();
}
}
Comment 1 Silenio Quarti CLA 2004-02-11 13:00:16 EST
Windows Xp Professinal Version 2002 Service Pack 1
Pentium 4 CPU 2.00GHz
512MB of RAM

Control drawString() - count=100000 time=1563 ms
Control stringExtent() - count=100000 time=672 ms
Image drawString() - count=100000 time=1313 ms
Image stringExtent() - count=100000 time=656 ms
Comment 2 Silenio Quarti CLA 2004-02-11 13:03:00 EST
Mac OS X Version 10.3.1
Dual 1.25 GHz PowerPC G4
2 MB L3 cache per processor
1GB DDR SDRAM

Control drawString() - count=100000 time=15905 ms
Control stringExtent() - count=100000 time=10701 ms
Image drawString() - count=100000 time=13494 ms
Image stringExtent() - count=100000 time=10562 ms
Comment 3 Silenio Quarti CLA 2004-02-11 13:28:16 EST
Mac OS X Version 10.2.8
Dual 1.25 GHz PowerPC G4
2 MB L3 cache per processor
1GB DDR SDRAM

Control drawString() - count=100000 time=29251 ms
Control stringExtent() - count=100000 time=15897 ms
Image drawString() - count=100000 time=23810 ms
Image stringExtent() - count=100000 time=15392 ms
Comment 4 Andre Weinand CLA 2004-02-11 13:59:41 EST
PowerBook G4 AL
Mac OS X Version 10.3.2
1.25 GHz PowerPC G4
512k L2 cache
0 MB L3 cache
1.5GB DDR SDRAM

java version "1.4.2_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-117.1)
Java HotSpot(TM) Client VM (build 1.4.2-34, mixed mode)

Control drawString() - count=100000 time=19218 ms
Control stringExtent() - count=100000 time=11150 ms
Image drawString() - count=100000 time=13708 ms
Image stringExtent() - count=100000 time=11085 ms
Comment 5 Mike Wilson CLA 2004-02-11 14:28:47 EST
Note: One line of the bench was wrapped at a bad spot (inside a string literal).
Comment 6 Mike Wilson CLA 2004-02-11 14:43:19 EST
That's definately faster than me, Andre ;-)

PowerBook G4 AL
Mac OS X Version 10.3.2
1 GHz PowerPC G4
512k L2 cache
0 MB L3 cache
1.5GB DDR SDRAM

java version "1.4.2_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-117.1)
Java HotSpot(TM) Client VM (build 1.4.2-34, mixed mode)

Control drawString() - count=100000 time=22934 ms
Control stringExtent() - count=100000 time=15211 ms
Image drawString() - count=100000 time=18847 ms
Image stringExtent() - count=100000 time=14706 ms
Comment 7 Silenio Quarti CLA 2004-02-12 13:17:15 EST
GTK - glib2-2.2.1-1/gtk2-2.2.1-4/pango-1.2.1-3
Intel(R) Pentium(R) 4 CPU 2.53GHz
Mem 512Mb

Control drawString() - count=100000 time=28093 ms
Control stringExtent() - count=100000 time=11064 ms
Image drawString() - count=100000 time=16439 ms
Image stringExtent() - count=100000 time=10852 ms
Comment 8 Silenio Quarti CLA 2004-02-12 15:22:31 EST
Motif
Intel(R) Pentium(R) 4 CPU 2.53GHz
Mem 512Mb

Control drawString() - count=100000 time=6959 ms
Control stringExtent() - count=100000 time=1768 ms
Image drawString() - count=100000 time=2643 ms
Image stringExtent() - count=100000 time=1736 ms
Comment 9 Andre Weinand CLA 2004-02-13 19:45:16 EST
This is a funny (sad?) one:

Windows 2000 on Virtual PC 6.1 on my PowerBook
(same configuration as comment 4)
JRE 1.4.1

Control drawString() - count=100000 time=8732 ms
Control stringExtent() - count=100000 time=1382 ms
Image drawString() - count=100000 time=3896 ms
Image stringExtent() - count=100000 time=1022 ms
Comment 10 MarkPalmer CLA 2004-02-24 19:13:25 EST
My results for Windows xp thinkpad celeron 1Ghz 512ram eclipse 3.0M7

Control drawString() - count=100000 time=1071 ms
Control stringExtent() - count=100000time=361 ms
Image drawString() - count=100000 time=1222 ms
Image stringExtent() - count=100000time=310 ms

I will post my results for same machine next
Comment 11 MarkPalmer CLA 2004-02-24 20:15:26 EST
These are my results for linux on the same thinkpad celeron 1Ghz 512ram as above
with eclipse 3.0M7

GTK 2.2.4 gnome 2.4 blackdown jvm 1.4

Control drawString() - count=100000 time=14662 ms
Control stringExtent() - count=100000time=9836 ms
Image drawString() - count=100000 time=17375 ms
Image stringExtent() - count=100000time=9944 ms

quite a performance difference
Comment 12 Steen Jansdal CLA 2004-02-25 03:44:17 EST
Comment to #7:

Note: Pango 1.2.5 is much faster than 1.2.1
Comment 13 Aaron Digulla CLA 2004-02-25 18:45:33 EST
I've added an attachment to Bug #37683 which should contain gc.drawString() 
from SWT. This attachment should have been made here. Sorry for that. 
 
There is a bug (I admit, it's a quick hack based on an example from GTK+) 
which slows it down tremendously but maybe this "bug" helps us to find why 
it's slow in SWT. 
 
See my comments at 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=37683#c156 
 
I guess if someone who knows about SWT can look at my code, he should be able 
to find the problem very quickly. If it looks OK, we can pass the benchmark on 
to Owen Taylor so he can have a look. Timings are with Pango 1.2.5. 
 
(Owen Taylor is responsible for Pango). 
 
See also 
http://bugzilla.gnome.org/show_bug.cgi?id=129473 
(Bug report at GNOME). 
Comment 14 Aaron Digulla CLA 2004-02-26 16:36:33 EST
There has been some confusion why my test contains gdk_draw_text(). The reason 
is that I wanted to see how fast string rendering can get (without AA, complex 
layout, etc). gdk_draw_text() is (almost) the fastest way to render a string, 
so no matter how much we improve Pango, we'll never get better than that. 
 
Basically, this test is there to decide whether we must avoid to render at all 
to get decent performance. 
 
I'll attach a new test in a minute which changes the numbers slightly: Now, 
they will show how many call/second the test can make. Benchmark3.java runs 
each test for 10 seconds, the C version for a fixed amount of time. 
 
Here are some figures: 
 
Java version: 
 
gc.drawText 1939 
gc.drawText 2 5409 
gc.stringExtent 6215 
gc.textExtent 6251 
 
C version: 
 
gc.gdk_draw_text 79923 
gc.drawText 1407 
gc.stringExtent 8600 
 
Notes: I've omitted textExtend because it's basically the same as stringExtent 
in SWT 3.0 
 
As you can clearly see, rendering directly is about ten times faster (80K 
against 8.6K) than getting the extent of the string via Pango which doesn't 
make sense in my eyes. I mean: It should take more time to copy a lot of pixel 
information into a complex bitmap than to add some numbers!? Even if you take 
the gfx hardward into account, my main CPU should still add numbers quicker 
than that. 
 
I'll add a comment to the respective bug in Pango. 
Comment 15 Aaron Digulla CLA 2004-02-26 16:42:02 EST
Created attachment 8198 [details]
V3 of the Java/C benchmark

Run the C version with "make c" and the Java version with "make gtk" after
copying all *.so and *.jar files from eclipse.swt.gtk_3.0.0 into the directory
Benchmark3/swt-gtk/
Comment 16 Aaron Digulla CLA 2004-02-26 17:06:05 EST
I've now started to take the code of GC.java apart. My benchmark already 
contains copies of the relevant code used in the tests in a class called 
MyGC.java which allows me to do some quick hacks. 
 
While doing so, I noticed something which made my worry: All methods on 
OS.java are synchronized. Why is that? Doesn't SWT already make sure that 
everything is single threaded? Creating such a tremendous amount of locks (we 
call these methods by the ton) is probably biting a big chunk out of the 
performance. 
 
Can one of the SWT developers, who can compile the C code of SWT, try to 
remove all the synchronized strings out of OS.java and run my benchmark once 
before and once after? 
Comment 17 Silenio Quarti CLA 2004-02-26 18:15:29 EST
OS must be synchronized because SWT graphics can happen in any thread.  If there
is more than a single thread in GTK at a time, it will GP.

On GTK, by commenting out OS.gdk_draw_layout_with_colors() in GC from
drawString() and OS.pango_layout_get_size() from stringExtent() it is clear that
all of the time is in these two Pango calls. Compare these results to comment #7.

GTK - glib2-2.2.1-1/gtk2-2.2.1-4/pango-1.2.1-3
Intel(R) Pentium(R) 4 CPU 2.53GHz
Mem 512Mb

Control drawString() - count=100000 time=1182 ms
Control stringExtent() - count=100000 time=1022 ms
Image drawString() - count=100000 time=962 ms
Image stringExtent() - count=100000 time=1005 ms
Comment 18 Steve Northover CLA 2004-02-26 18:18:21 EST
Aaron, the benchmark we are using for string drawing and measuring is 
StringBench.  It's much simpler.  Feel free to construct a similar C benchmark 
and post the times.  Thanks.
Comment 19 Aaron Digulla CLA 2004-02-26 18:27:53 EST
> comment #17: 
> OS must be synchronized because SWT graphics can happen in any thread. 
> If there is more than a single thread in GTK at a time, it will GP. 
 
I know; the interesting question is: How much performance would this give? 
 
It should be simple to create a version of OS.java without synchronization. If 
that gives >> 10%, then it might be worth it to create OS and UOS 
(unsynchronized). The latter calls could be used when SWT components render 
themselves. 
 
> On GTK, by commenting out OS.gdk_draw_layout_with_colors() in GC from 
> drawString() and OS.pango_layout_get_size() from stringExtent() it is 
> clear that all of the time is in these two Pango calls. Compare these 
> results to comment #7 
 
Yes, I can second that. Taking all code out of MyGC.java except these two 
calls doesn't change the timing much. 
 
> comment #18: 
> Use StringBench 
 
Well, I guess we have nailed it down but I can have a look if StringBench is 
really different from my benchmark. Where can I find it? 
Comment 20 Steve Northover CLA 2004-02-26 18:33:43 EST
It's in this bug report (but not as an attachment).

You can't have some methods synchronized and some not or you will GP.  Only 
one thread, GUI or non-GUI can be in GTK at a time.
Comment 21 Aaron Digulla CLA 2004-02-26 18:47:21 EST
> StringBench 
 
My benchmark does basically the same thing; turning StringBench into C 
wouldn't yield any new insights because the complex stuff was to convert 
drawString() from SWT to C. 
 
> Synchronized stuff 
 
Ok, then how about a more global lock? SWT components could get the lock in 
the redraw() method (or repaint() or whatever it is called). Then, java 
wouldn't need to sync for every OS call. IIRC, Java just ignores a lock which 
you already own. 
 
But the point here is: Would it be worth it? Can someone please give it a try? 
maybe the performance impact of this is so small that this whole discussion is 
mute. OTOH, if the impact is big, it might be worth it. But unless this 
question is answered, all conclusions are useless. 
Comment 22 Aaron Digulla CLA 2004-02-26 19:03:42 EST
After a little more thinking, the solution is quite simple: Just add 
 
....synchronized (OS.class) { 
 
....} 
 
around the rendering code; that's what the "native synchronized" statements do 
in OS.java. The results are interesting: Simple calls like gc.setLineWidth() 
get 10 times faster while gc.drawText() almost doesn't change. Overall, I'd 
say the speedup is roughly 5-10%. 
 
Since it's simple to apply, I'd suggest to post a comment on the SWT developer 
list. Components with a complex redraw method can then add these two lines and 
get some extra speed (almost) for free. 
Comment 23 Steve Northover CLA 2004-02-26 19:52:21 EST
We already have the lock in paint because paint happens when the event is 
dispatched and dispatching acquires the lock.  Simple calls get faster because 
the time is in acquiring the lock, not querying the OS.

Over all, I don't think it's worth it.  Perhaps you could try running 
Benchmark2 from #32683 and publishing the results there?  This report concerns 
string draw.  Thanks.
Comment 24 Steve Northover CLA 2004-02-26 19:53:31 EST
Oops, bug #37683 ...
Comment 25 Aaron Digulla CLA 2004-03-01 14:33:26 EST
Re: #23 and #24: My benchmark tests string drawing and line drawing to make 
sure that I test the same things as Benchmark2. So the timings of Benchmark3 
are in fact compatible to Benchmark2 (my tests just show how many calls can be 
made per second while Bench2 shows how long 1 million calls take; the latter 
is IMHO easier to compare). 
 
As for the lock: I've searched the whole source with grep -r and couldn't find 
a place where a lock to OS.class is acquired, so I think that you're wrong 
there: You get a new lock each time you call on gtk function and that can be 
expensive. 
 
For a fix, I suggest to add a lock in Display.readAndDispatch(). Should give 
any SWT app on GTK a free performance boost of about 2-5%. 
Comment 26 Aaron Digulla CLA 2004-03-01 15:12:44 EST
Owen Taylor of GNOME fame answered my questions regarding to Pango. Here is 
what he said (see the full reply at 
http://bugzilla.gnome.org/show_bug.cgi?id=129473): 
 
- [...] Text drawing is another matter, I know plenty of things 
  that could be done to make AA text drawing 10 times or 
  more faster, but X development is a huge mess at the moment. 
 
So text rendering is just plain slow, especially when we want to use AA text 
rendering. 
 
Then I asked how about a special handler for ASCII. His reply: 
 
- Special casing ASCII is not interesting to me, because 
  as soon as I do that, application authors lose touch 
  with how their app will perform for many of their  
  users. 
 
- Modern processors do well in tight loops. This is why 
  it's easy to make blitting a few bitmap characters 
  faster than analyzing the same characters and laying 
  them out. Plus XDrawText tends to be HW accelerated 
  (though it's plenty fast enough in software) 
 
Comment: XDrawText is fast because it's in HW while AA rendering is usually 
not accelerated. 
 
- Your timings above indicate that in your benchmark, the 
  real bottleneck is Xft drawing, not Pango layout.  
  By doing measurements of what Eclipse does in real 
  applications, you'd be able to figure out if that 
  is the case in real life as well. 
 
Comment: So I guess this means that using Xft directly won't help much. 
 
- I took a short look at the C benchmark yesterday, and other 
  than setting the background in draw_layout_line_with_colors() 
  it's not doing anything obviously stupid that would  
  cause noticeable performance updates. 
 
Comment: Clearing the background can be expensive. That is why most apps draw 
the background and then just render the text over it. 
 
- Applications that want to look reasonable usually draw 
  to a backing pixmap, this prevents the user seeing 
  clear/redraw flashing. I assume that SWT does this 
  in some fashion, but then again, maybe not... 
 
  GDK provides a nice convenient interface to this 
  with gdk_window_begin_paint_rect/region(), though 
  apps can also do it manually if they want. 
 
Comment: I haven't seen any place where SWT renders to an offscreen bitmap. 
Does it? 
 
If it doesn't, is that an option? 
 
- Whether drawing to an offscreen pixmap is faster 
  or not than drawing to the screen depends a lot 
  on particular system details. Because of deficencies 
  in XFree86, it is occasionally *much* faster, but 
  it's not reliably faster. 
 
Comment: Since X allows to redirect the display to another computer, it must 
make some compromises. When you look at it as a client/server architecture, 
then the app is a client of a server which can draw on a screen. This means 
that any drawing command must be converted to a network format (a binary 
string), transported over some kind of socket (TCP/IP or a socket on disk 
in /tmp/.X11-unix/) and then the server can execute it. 
 
That's the reason why avoiding drawing something saves so much time. 
 
Just in the last few years, things like shared memory have started to come up 
which enhanve performance considerably. So today, it's possible to request a 
shared pixmap from the server (only locally, so you cannot start a program 
which uses this over a network) and render directly to it. This is fast but 
not very portable. 
 
Conclusion: The only way to get SWT text rendering faster by an order or two 
(which is what we're after), we must drop Pango and AA text rendering or wait 
for someone to optimize XFree86. 
Comment 27 Steve Northover CLA 2004-03-01 15:48:03 EST
Arron, WRT comment #25, the method OS.gtk_main_iteration() inside of 
Display.readAndDispatch() acquires the lock when it dispatches an operating 
system event.
Comment 28 Steve Northover CLA 2004-03-01 15:53:44 EST
> Conclusion: The only way to get SWT text rendering faster by an
> order or two (which is what we're after), we must drop Pango and
> AA text rendering or wait for someone to optimize XFree86. 

We are never dropping Pango as long as GTK embraces it.
Comment 29 Aaron Digulla CLA 2004-03-01 16:22:09 EST
Re #27: What about the rendering in runDeferredEvents()? Doesn't SWT collect 
all rendering events and then dispatch them all at once? 
Comment 30 Steve Northover CLA 2004-03-01 16:25:16 EST
No.  Some events are queued, some are not.  Paint events are not queued.
Comment 31 Aaron Digulla CLA 2004-03-01 17:04:14 EST
Re #28: If we must use Pango, then the only options are to heavily optimize  
Eclipse to make sure that we never draw anything unecessarily and to try to  
render the text widget to an offscreen bitmap.  
Comment 32 Aaron Digulla CLA 2004-03-02 16:18:45 EST
Created attachment 8279 [details]
StyledText benchmark

This is a simple benchmark which shows how fast StyledText is during rendering.
Here are the timings on my Linux box:

set no text 1567
setText 1 line 549
setText 2 lines 437

Whether I lock OS or not doesn't change the results much.
Comment 33 Aaron Digulla CLA 2004-03-02 16:26:55 EST
When you look at the timings in comment 32 and the ones in V3 of the 
benchmark, you can see that drawing using drawString() is four to ten times 
faster than styledText.getContent().setText("two\nlines"); 
styledText.repaint(); 
 
Can someone with a working profiles run StyledText benchmark, please? I'd like 
to see in which calls the time gets lost. I mean, drawString() is slow 
already ... 
 
And something else which I noticed: On Windows, text rendering is non-AA. 
Maybe someone can investigate how to disable AA in Pango? 
Comment 34 Aaron Digulla CLA 2004-03-03 04:12:44 EST
On a WinNT 4.0SP6a system with Pentium III/1Ghz and onboard Intel gfx, I get 
this:

WinNT 4.0 without OS lock

set no text 471
setText 1 line 226
setText 2 lines 221

WinNT 4.0 with OS lock

set no text 502
setText 1 line 236
setText 2 lines 223

Again, the OS lock doesn't seem to change much. What is interesting, though, is 
the fact that Eclipse feels more responsive on this HW, while it still is much 
inferiour to my PC at home (dual P-III with 1GHz and an NVIDIA gfx card).

The UI of Eclipse 3.0M7 still feels much less responive than 2.1.2 on it except 
for some things: Speed of the text rendering feels OK but input sometimes lags 
begind. Also, java completion is sometimes instantly and sometimes takes a 
rather long coffee break.

From these observations, I conclude that the speed of string rendering alone is 
not the sole cause of the performance problems which we experience on Linux.

So again, the old saying hold true: It's impossible to say where the 
performance goes to by looking at the source and guessing. One must use a 
profiler.

Can someone direct me to a (free/OSS) profiler which I can download and run 
Eclipse in so I can get some real numbers?
Comment 35 Aaron Digulla CLA 2004-03-03 08:02:50 EST
After running StyledText benchmark on WINDOWS(!) in hyades, I find that 75% of 
the time is spent in these three methods:

- Display.getLastEventTime() (called from Widget.sendEvent())
- StyledText.performPaint() calls OS.getDC() (via GC.GC() ->
  Image.internal_new_GC() -> Display.internal_new_GC(GCData))
- StyledText.performPaint() eventually gc.dispose() which calls OS.releaseDC()

It seems to me that (like on Unix), getting the current system time and 
creating/disposing GCs is expensive.

So I tried to optimize these two. Sun did put some effort into enhancing 
System.currentTimeMillis(), so I thought I could use that instead of 
getLastEventTime() (a benchmark shows that cTM() is 2-3 times faster than gLET
()) but I don't know the semantics of gLET() and there is no javadoc comment in 
Display.java. Anyone?

Next, I cached the image and GC in performPaint(). Here are the timings for 
this:

WinNT 4.0 without caching:

set no text 502
setText 1 line 236
setText 2 lines 223

With cached line buffer:

set no text 832
setText 1 line 399
setText 2 lines 384

That's about 1.6 times faster. Tonight, I'll try the same on Linux and send you 
a patch for StyledText so everyone can have a look.
Comment 36 Andre Weinand CLA 2004-03-03 08:42:22 EST
I don't know whether the following is relevant to you, but StyledText (probably the biggest and most 
important client of string rendering), implements its own double buffering mechanism.
See StyledText.performPaint(...).
Comment 37 Steve Northover CLA 2004-03-03 10:51:43 EST
Yes, fixing string drawing won't fix Eclipse.  This problem report is focusing 
on string drawing because it is a known area where Windows is faster than 
every other platform.
Comment 38 Steve Northover CLA 2004-03-03 10:57:40 EST
Is your Profiler lying?  Try making Display.getLastEventTime() return zero.  
Is everything faster?  Also, your benchmarks should measure times over one 
second (longer times are better).  This helps with benchmark stability.
Comment 39 Aaron Digulla CLA 2004-03-03 16:06:34 EST
Created attachment 8318 [details]
Patch against M07 SWT source

Ok, I've now verified my patch. On linux, I get about 80-100% better
performance from my StyledText benchmark when using a cache for the GC and the
Image used in StyledText to do double buffering in performPaint().

Some background: The patch caches the image which is created in performPaint.
Next time when the method is called, the patch checks if the image is large
enough (the widget might have been resized), allocates a larger image if
necessary, and then copies the damaged part of the image into the destination
drawable.

Please have a look and if you like the patch (except for the indentation ;-),
include it in M8.
Comment 40 Aaron Digulla CLA 2004-03-03 16:09:03 EST
Re comment 38: 
 
> Is your Profiler lying? 
 
Well, it seems that hyades has an issue with Display.getLastEventTime(). You 
can ignore this part of my post. 
Comment 41 Steve Northover CLA 2004-03-03 18:49:38 EST
Felipe, can you check out the M07 SWT source patch and associated benchmark.  
Thanks.
Comment 42 Steen Jansdal CLA 2004-03-04 02:17:57 EST
Re #39:

Wow, 80-100% better performance. I'll definitely try
your patch later. Right now I'm very busy.

One comment: Is there any particularly reason to test if 1 == 0?

+                  if (1 == 0 || lineBuffer == null
+                    || lastLineSize.x < clientArea.width
+                    || lastLineSize.y < renderHeight
+
+                )
Comment 43 Steen Jansdal CLA 2004-03-04 02:27:54 EST
Re #37:

>> This problem report is focusing 
>> on string drawing because it is a known area where Windows is faster than 
>> every other platform.

Windows isn't necessarily faster than every other platform. FOX is
actually faster at string drawing.
Comment 44 Aaron Digulla CLA 2004-03-04 04:20:28 EST
Re #42: 

> 1 == 0

That was just to be able to disable the test quickly :-) I missed that when I 
cleaned the patch.
Comment 45 Steen Jansdal CLA 2004-03-04 04:34:47 EST
Re #44 :

Nah, I done buy that ;-)  You can't disable the test by
altering 1==0 to 1==1 or something else. 

But any way, forget it, I'm only teasing. I'm really looking
forward to try your patch. :-)
Comment 46 Felipe Heidrich CLA 2004-03-04 12:19:58 EST
I tested Aaron's patch and it made StyledText slower for me.
My testcase is to put a whole bunch of text and a few styles on the StyledText
and measure the time to draw/update 200 times.
My machine is a IBM IntelliStation Z Pro running RedHat 9.
Results:
No Patch:
Time: 7401 (ms), Time: 7319 (ms), Time: 7775 (ms), Time: 6935 (ms)

Patch:
Time: 10127 (ms), Time: 9818 (ms), Time: 10138 (ms), Time: 10156 (ms)
Comment 47 Felipe Heidrich CLA 2004-03-04 12:21:01 EST
Created attachment 8332 [details]
Felipe's benchmark
Comment 48 Aaron Digulla CLA 2004-03-04 14:16:21 EST
Re #46: 
 
> Patch makes things slower in Felipe's benchmark 
 
I can second that, here are my numbers: 
 
With: 9475 7368 7180 7119 
Without: 7997 6366 6861 6296 6177 
 
Observations: 
 
1. The test becomes faster with every iteration. Why is this? 
 
2. I've added a counter in GC(Drawable,boolean). It shows that during each 
test run, about 500 GCs are created. Is it possible that the syntax 
highlightning always creates new GCs? 
 
When I start Eclipse and scroll around a bit, about 100 GCs/s are created (and 
destrory). 
 
Since my benchmark shows that creating GCs is costly, I'll run Felipe's 
benchmark with the profiler to see where these GCs are created. 
Comment 49 Steen Jansdal CLA 2004-03-05 02:24:13 EST
Aaron, I've tried your patch, but I'm afraid I havn't
been able to measure any significant difference.

I've measured the time spent in performPaint by inserting

long start = System.currentTimeMillis(); 

as the first line and

long stop = System.currentTimeMillis(); 
System.out.println ( " " + (stop-start) ); 

as the last lines. By scrolling up and down in the javaviewer
example I haven't seen performPaint go faster than 45 ms
(on my 233 Hz dinosaur), with or without your patch.

What is interesting is that even thou performPaint uses
45 ms to do a redraw there is approx. 1/2 sec from I hit 
the PageDown key until I see the update on the screen. 

Something very rotten is going on and I think we shall find
the answer somewhere in GTK or how the event queue are 
implemented. String drawing or measuring are very slow but 
I actually don't think its our biggest problem.
Comment 50 Aaron Digulla CLA 2004-03-05 15:23:38 EST
Re #49: 
 
> Routine doesn't get faster with patch 
 
Steen, this is simply not possible. There must be a speed difference. (for 
example, I allocate the image just once). Can you put a System.out in there to 
see how often the image is created? Here, it's created two times: Once, when 
the component is created and then again, when it is scrolled for the first 
time. 
 
A possible explanation could be that currentTimeMillis() can't time something 
with less than 45ms on your hardware. Because of some optimizations which Sun 
has made in this call, it's not reliable with small timings (I have a 
"resolution" here of about 10ms). 
 
Suggestion: Add a counter and print the time only after 10 or 100 invocations. 
Comment 51 Steve Northover CLA 2004-03-05 17:16:48 EST
In order to get real numbers, you need to measure things that are greater than 
one second (the longer the better).
Comment 52 Steve Northover CLA 2004-10-04 12:59:09 EDT
*** Bug 4585 has been marked as a duplicate of this bug. ***
Comment 53 Steve Northover CLA 2004-10-04 13:00:51 EDT
*** Bug 4615 has been marked as a duplicate of this bug. ***
Comment 54 Andre Weinand CLA 2005-03-25 12:22:11 EST
PowerBook G4 AL
Mac OS X 10.4 (8A393)
1.25 GHz PowerPC G4
512k L2 cache
0 MB L3 cache
2GB DDR SDRAM

java version "1.4.2_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_07-200)
Java HotSpot(TM) Client VM (build 1.4.2-49, mixed mode)

Control drawString() - count=100000 time=15363 ms
Control stringExtent() - count=100000 time=10073 ms
Image drawString() - count=100000 time=14187 ms
Image stringExtent() - count=100000 time=10030 ms
Comment 55 Andre Weinand CLA 2006-02-18 04:59:10 EST
iMac	Intel Core Duo 1.83 GHz
Mac OS X 10.4.5 (8G1454)
L2 Cache (shared): 2 MB
Memory: 1.5 GB
Bus Speed: 667 MHz

java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-103)
Java HotSpot(TM) Client VM (build 1.5.0_06-57, mixed mode)

Control drawString() - count=100000 time=8228 ms
Control stringExtent() - count=100000 time=5054 ms
Image drawString() - count=100000 time=7456 ms
Image stringExtent() - count=100000 time=5094 ms
Comment 56 Ian Bull CLA 2006-04-24 16:48:19 EDT
Debian Unstable (AMD 2.4Ghz, 2G Ram, Nvidia GeForce FX 5200)
GTK 2.8.17-1
Pango 1.12.1-2
Cario 1.0.4-1

Control drawString() - count=100000 time=30911 ms
Control stringExtent() - count=100000time=9714 ms
Image drawString() - count=100000 time=30414 ms
Image stringExtent() - count=100000time=9628 ms

I enabled advanced graphics (gc.setAdvanced(true))
and got:

Control drawString() - count=100000 time=9646 ms
Control stringExtent() - count=100000time=10001 ms
Image drawString() - count=100000 time=8703 ms
Image stringExtent() - count=100000time=9710 ms

About 3x faster. However, enabling advanced (cairo) graphics slows down fill* routines considerably (things like fillRectangle, etc...).

One of the things I read about text performance is that AA is slow on linux (http://vektor.ca/eclipse/gtk-performance-notes.html).  Owen Taylor said that pango is naturally slower than motif because it does a lot more.  I am wondering if we *have* to do a lot more.  I think Pango does a great job, but is there a way to (programmatically) turn some of these features off (or maybe this is a really bad idea).  I tired gc.setAntialias(SWT.OFF) but this had not effect on the performance numbers.  

I also tried to disable AA in my fonts.conf file, but again no change.  

Also, in http://bugzilla.gnome.org/show_bug.cgi?id=129473, Owen says that Pango can draw about 9,000 8 digit numbers in a second.  The numbers in this bug report suggests that windows can draw close to 10x that amount in a second.  I don't know how much it will effect eclipse performance, but I am personally working on an application that requires animation and I am trying to get my FrameRate up :)

- ian
Comment 57 Steve Northover CLA 2006-04-24 16:57:37 EDT
It's the 3.2 end game so we aren't really looking at this.  If you comment out all string drawing either in your application or in SWT (just make it do nothing), does your frame rate go up?
Comment 58 Andre Weinand CLA 2006-04-24 18:06:03 EDT
MacBook Pro    Intel Core Duo 2 GHz
Mac OS X 10.4.6 (8I1119)
L2 Cache (shared): 2 MB
Memory: 2 GB
Bus Speed: 667 MHz

java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-112)
Java HotSpot(TM) Client VM (build 1.5.0_06-64, mixed mode, sharing)

Control drawString() - count=100000 time=7652 ms
Control stringExtent() - count=100000 time=4774 ms
Image drawString() - count=100000 time=6886 ms
Image stringExtent() - count=100000 time=4735 ms


And now the fun part:

Same benchmark on Windows XP Professional SP2
running on same hardware inside
Parallels Workstation 2.11 Beta4 for Mac OS X

java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)

Control drawString() - count=100000 time=2744 ms
Control stringExtent() - count=100000 time=100 ms
Image drawString() - count=100000 time=2123 ms
Image stringExtent() - count=100000 time=140 ms
Comment 59 Ian Bull CLA 2006-04-24 19:11:08 EDT
(In reply to comment #57)
> It's the 3.2 end game so we aren't really looking at this.  If you comment out
> all string drawing either in your application or in SWT (just make it do
> nothing), does your frame rate go up?
> 

Thanks for the quick reply Steve.
I know the end game is here, and I am not expecting a fix anytime soon, I just wanted to post these numbers while I had them available. I am not even sure this is an SWT problem.  I think SWT performance on GTK+ has improved tenfold since the early days of eclipse :)

As for my FPS, yep it more than doubles when I remove the text rendering.  It goes from about 8 to 16 FPS when I am not rendering the text.  It is currently rendering about 5,000 chars.  This doesn't tell us much because I would expect it to improve without the text rendering.  An interesting note is that when I remove the text drawing from windows it doesn't change the performance much.

- ian
Comment 60 Billy Biggs CLA 2006-04-26 00:03:47 EDT
Pango can be slow, but we did some good work to make it faster
in pango 1.12.  For more details and pointers, see Federico's activity
log from October:

  http://primates.ximian.com/~federico/news-2005-10.html

If you want to know more about how to optimize pango, drop by
#performance on irc.gimp.org sometime and we can talk about it.
There are some more things in the profiles that can be brought
down if you're interested in hacking around.
Comment 61 Ian Bull CLA 2006-07-19 15:36:08 EDT
I have spent a few days hacking with GTK and Pango (Just using them to get some idea how they work).  I now have a better understanding of what Pango does and why it runs slower than Windows (and even AWT) font rendering.  Pango does a much better job of text layout than any of these other tools (especially for scripts and international fonts).  

However, in some application areas you just want to render labels (character arrays) at pre-determined X,Y locations without the full pango pipeline.  (For example: an information visualization tool for medical ontologys rendering and animating hundreds of medical terms).  Some GTK users have suggested I bypass Pango and just draw to X directly (I didn't mention to them I was doing this through SWT).  So this got me thinking, can we address this bug by adding a Quality flag to SWT that is a "hint" about how high quality we want the rendering?  If we want High Quality then SWT.GTK could use Pango (the default), and if we don't care about quality, then we can simply bypass it and use gdk_draw_string (I know it is deprecated) or some other lower level text primitive?

Cheers,
Ian
Comment 62 Steve Northover CLA 2006-07-26 10:24:36 EDT
We looked into this a while back and decided against it (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=37683#c134).

In your application, if you knew that you were on GTK, only drawing English text, didn't care about the font, etc, etc, you could call the low level X, xft, or GDK text drawing routines.
Comment 63 Ian Bull CLA 2006-07-26 10:43:02 EDT
Thanks Steve.

I am actually doing this in Draw2D / GEF.  I extended their label and I am now caching the entire label to an image.  I invalidate the image if the text changes (or the size changes) but since the most common operation is move, I can just reuse the image.  This has greatly improved performance.  When I do scaling animations, I do a mix of scaling the image and occasionally re-draw the text (like google maps).  

I may try your solution with the low level calls. Are these exposed through the GC or OS layer?  I didn't see them there, but there are a lot of routines.  ( I guess it would have to be in the OS layer since it is specific to GTK).

Cheers,
Ian
Comment 64 Steve Northover CLA 2006-07-26 11:42:00 EDT
At one point the natives were there but Billy deleted them.
Comment 65 Scott Kovatch CLA 2006-08-17 11:17:54 EDT
Adding to Java benchmarks for Leopard. This will make it more visible inside Apple.
Comment 66 Ian Bull CLA 2006-12-19 17:43:39 EST
Because nobody notices when things improve, I thought I would post this:
GTK+ Debian Unstable
Pango 2.14.8-3
AMD 3800+

Control drawString() - count=100000 time=14151 ms
Control stringExtent() - count=100000time=4865 ms
Image drawString() - count=100000 time=13790 ms
Image stringExtent() - count=100000time=4848 ms

This is about 2x faster than before.  Pango has come a long way.  And while it is still slower than Windows, I personally think the fonts look nicer.
Comment 67 Behdad Esfahbod CLA 2006-12-19 20:01:50 EST
Interesting.  You should test Pango HEAD and cairo master branch.
Comment 68 Andre Weinand CLA 2007-01-04 06:43:20 EST
MacBook Pro    Intel Core 2 Duo 2.33 GHz
Mac OS X 10.4.8 (8N1037)
L2 Cache (shared): 4 MB
Memory: 3 GB
Bus Speed: 667 MHz

java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-113)
Java HotSpot(TM) Client VM (build 1.5.0_06-68, mixed mode, sharing)

SWT 3320:

Control drawString() - count=100000 time=6352 ms
Control stringExtent() - count=100000 time=3604 ms
Image drawString() - count=100000 time=4747 ms
Image stringExtent() - count=100000 time=3607 ms

And again the fun part:

Same benchmark on Windows XP Professional SP2
running on same hardware inside
Parallels Desktop for Mac
Build 3106 Beta 3 (28. Dezember 2006)

java version "1.5.0_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)
Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode, sharing)

Control drawString() - count=100000 time=1662 ms
Control stringExtent() - count=100000 time=80 ms
Image drawString() - count=100000 time=1512 ms
Image stringExtent() - count=100000 time=80 ms
Comment 69 Behdad Esfahbod CLA 2007-01-04 11:15:06 EST
Latest pango 1.15.x and cairo 1.3.x should give you something very near the Windows performance for extents, and not much worse for rendering.
Comment 70 Steve Northover CLA 2007-01-04 11:21:02 EST
Behdad, please post the results.
Comment 71 Behdad Esfahbod CLA 2007-01-04 11:36:11 EST
(In reply to comment #70)
> Behdad, please post the results.

Umm, I've been trying to seduce someone to try and post results :).  Without being lazy, I'm far from that high in the stack to tinker with SWT (or Java for that matter).  Andrew, maybe you can do that?
Comment 72 Andrew Overholt CLA 2007-01-04 11:41:57 EST
(In reply to comment #71)
> (In reply to comment #70)
> > Behdad, please post the results.
> 
> Umm, I've been trying to seduce someone to try and post results :).  Without
> being lazy, I'm far from that high in the stack to tinker with SWT (or Java for
> that matter).  Andrew, maybe you can do that?

Yeah, I've been meaning to do this.  I'll try to get to it today.

Comment 73 Felipe Heidrich CLA 2007-01-04 12:27:47 EST
Kevin, you also have an intel mac os running Parallels with vista and fc6. Check comment #68, can you test it too ?
Comment 74 Ian Bull CLA 2007-01-04 13:49:27 EST
I got the latest pango and cairo graphics and gave this a try.  With gc.setAdvanced(true) I get slightly better results, but still not near windows performance.  (with it set to false I get the same as before)

Control drawString() - count=100000 time=11221 ms
Control stringExtent() - count=100000time=5230 ms
Image drawString() - count=100000 time=11381 ms
Image stringExtent() - count=100000time=5506 ms

Maybe there is something wrong with my install:
(Everything else is from Debian unstable, pango and cairo and build from their latest release, SWT is from 3.3M4).

duff:~# ldconfig -v | grep cairo
        libsvg-cairo.so.1 -> libsvg-cairo.so.1.0.1
        libpangocairo-1.0.so.0 -> libpangocairo-1.0.so.0.1502.0
        libcairo.so.2 -> libcairo.so.2.10.3

duff:~# ldconfig -v | grep pango
        libpangomm-1.4.so.1 -> libpangomm-1.4.so.1.0.29
        libpangocairo-1.0.so.0 -> libpangocairo-1.0.so.0.1502.0
        libpangoxft-1.0.so.0 -> libpangoxft-1.0.so.0.1400.8
        libpangox-1.0.so.0 -> libpangox-1.0.so.0.1400.8
        libpango-1.0.so.0 -> libpango-1.0.so.0.1502.0
        libpangoft2-1.0.so.0 -> libpangoft2-1.0.so.0.1502.0

Are these the versions you expect? 

What exactly does advanced graphics do for font rendering?



Comment 75 Behdad Esfahbod CLA 2007-01-04 15:09:28 EST
(In reply to comment #74)
> I got the latest pango and cairo graphics and gave this a try.  With
> gc.setAdvanced(true) I get slightly better results, but still not near windows
> performance.  (with it set to false I get the same as before)

Ok, I need to dig into seeing what the test and SWT are doing then.  The 80ms time for extents computation for 100000 iterations can only mean one of two things: 1) bogus measurement, 2) cached extents.

If cached extents is the case, then it should be possible to do the same on pango.  Pango 1.15.2 caches layout extents if you use it properly, so now it's down to swt to use it properly (cache the layout, and use the readonly accessors).  Read:

  http://mail.gnome.org/archives/gtk-devel-list/2006-December/msg00105.html

> Control drawString() - count=100000 time=11221 ms
> Control stringExtent() - count=100000time=5230 ms
> Image drawString() - count=100000 time=11381 ms
> Image stringExtent() - count=100000time=5506 ms
> 
> Maybe there is something wrong with my install:
> (Everything else is from Debian unstable, pango and cairo and build from their
> latest release, SWT is from 3.3M4).
> 
> duff:~# ldconfig -v | grep cairo
>         libsvg-cairo.so.1 -> libsvg-cairo.so.1.0.1
>         libpangocairo-1.0.so.0 -> libpangocairo-1.0.so.0.1502.0
>         libcairo.so.2 -> libcairo.so.2.10.3
> 
> duff:~# ldconfig -v | grep pango
>         libpangomm-1.4.so.1 -> libpangomm-1.4.so.1.0.29
>         libpangocairo-1.0.so.0 -> libpangocairo-1.0.so.0.1502.0
>         libpangoxft-1.0.so.0 -> libpangoxft-1.0.so.0.1400.8
>         libpangox-1.0.so.0 -> libpangox-1.0.so.0.1400.8
>         libpango-1.0.so.0 -> libpango-1.0.so.0.1502.0
>         libpangoft2-1.0.so.0 -> libpangoft2-1.0.so.0.1502.0
> 
> Are these the versions you expect? 

Assuming that SWT is using pangocairo, yes.

> What exactly does advanced graphics do for font rendering?

No idea.
Comment 76 Ian Bull CLA 2007-01-04 16:13:01 EST
(In reply to comment #75)
> > What exactly does advanced graphics do for font rendering?
> 
> No idea.

Sorry, that question was for the SWT team.  No worries, I have figured it out.  When advanced graphics is true SWT uses: (with some additional setup of course)

Cairo.cairo_move_to(cairo, x, y);
OS.pango_cairo_show_layout(cairo, data.layout

to actually render the text.

When it is set to false it uses:
int /*long*/ pixmap = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), width, height, -1);
if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);
int /*long*/ gdkGC = OS.gdk_gc_new(pixmap);
OS.gdk_gc_set_foreground(gdkGC, black);
OS.gdk_draw_rectangle(pixmap, gdkGC, 1, 0, 0, width, height);
OS.gdk_gc_set_foreground(gdkGC, data.foreground);
OS.gdk_draw_layout_with_colors(pixmap, gdkGC, 0, 0, layout, null, background);
OS.g_object_unref(gdkGC);
OS.gdk_draw_drawable(data.drawable, handle, pixmap, 0, 0, x, y, width, height);
OS.g_object_unref(pixmap);

I am currently trying to strip out only the OS layer (the native methods) that SWT uses to perform the benchmark.  This may help determine if SWT is using Pango correctly.   
Comment 77 Behdad Esfahbod CLA 2007-01-04 16:22:22 EST
(In reply to comment #76)
> (In reply to comment #75)
> > > What exactly does advanced graphics do for font rendering?
> > 
> > No idea.
> 
> Sorry, that question was for the SWT team.  No worries, I have figured it out. 
> When advanced graphics is true SWT uses: (with some additional setup of course)
> 
> Cairo.cairo_move_to(cairo, x, y);
> OS.pango_cairo_show_layout(cairo, data.layout

This is fine, assuming that OS.pango_cairo_show_layout calls pango_cairo_show_layout().

> to actually render the text.
> 
> When it is set to false it uses:
> int /*long*/ pixmap = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), width, height,
> -1);
> if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);
> int /*long*/ gdkGC = OS.gdk_gc_new(pixmap);
> OS.gdk_gc_set_foreground(gdkGC, black);
> OS.gdk_draw_rectangle(pixmap, gdkGC, 1, 0, 0, width, height);
> OS.gdk_gc_set_foreground(gdkGC, data.foreground);
> OS.gdk_draw_layout_with_colors(pixmap, gdkGC, 0, 0, layout, null, background);
> OS.g_object_unref(gdkGC);
> OS.gdk_draw_drawable(data.drawable, handle, pixmap, 0, 0, x, y, width, height);
> OS.g_object_unref(pixmap);

This is not optimal, to say the least.  No idea why a temp pixmap is used.

> I am currently trying to strip out only the OS layer (the native methods) that
> SWT uses to perform the benchmark.  This may help determine if SWT is using
> Pango correctly.   

Thanks.  A tool you may find useful is the bprobe tool in GNOME svn.  With bprobe, you can write probes really quickly to see for example how many times pango_layout_new() is called, without recompiling pango or SWT.  Let me know if you need help with that.
Comment 78 Ian Bull CLA 2007-01-04 16:54:37 EST
I'll look into the profiler, it may help, but for now I have isolated a few lines that seem to be causing some of the slowness (at least on the text extent part).

time = -System.currentTimeMillis();
for (int i=0; i<COUNT; i++) {
  OS.pango_layout_set_text(layout, new byte[]{'a','b','c','d','e'}, 5);
  int[] width = new int[1], height = new int[1];
  OS.pango_layout_get_size(data.layout, width, height);
  OS.pango_layout_set_text(layout, new byte[]{'f','g','h','i','j'}, 5);
  OS.pango_layout_get_size(data.layout, width, height);
}
System.out.println (msg + " stringExtent() - count=" + COUNT + "time=" + (System.currentTimeMillis() + time) + " ms");

This takes about 5 seconds for 100,000 iterations.
The OS.* simply call the native methods with the same name.  This is (basically) the way SWT is using Pango to calculate text extents.  It is much faster if you don't change the text during each iteration, but I don't think that is realistic. 

If GTK is < 2.8 it uses:

cairo_font_extents_t font_extents = new cairo_font_extents_t();
Cairo.cairo_font_extents(cairo, font_extents);
cairo_text_extents_t extents = new cairo_text_extents_t();
Cairo.cairo_text_extents(cairo, buffer, extents);


Comment 79 Andrew Overholt CLA 2007-01-04 17:12:09 EST
I'm obviously doing something wrong but I can't think of what it is.  I can't get StringBench to run on gtk64.  I've got 3.3M4 and the 1.5 Sun 64-bit JVM.  3.3M4 runs fine but StringBench gives:

Exception in thread "main" java.lang.UnsatisfiedLinkError: memmove
	at org.eclipse.swt.internal.gtk.OS.memmove(Native Method)
	at org.eclipse.swt.internal.Converter.wcsToMbcs(Converter.java:67)
	at org.eclipse.swt.internal.Converter.wcsToMbcs(Converter.java:54)
	at org.eclipse.swt.widgets.Display.<clinit>(Display.java:126)
	at tests.StringBench.main(StringBench.java:30)

I'm using Fedora 6.  Any help appreciated.
Comment 80 Ian Bull CLA 2007-01-04 17:33:26 EST
How are you launching the Java application?  From within Eclipse?  Sorry, I am using the 32 bit version of everything.  Does anyone know if GTK64 properly gets the .SO file out of the JAR file (the work in Bug #166865)

Also, 
What happens if you wrote:
time = -System.currentTimeMillis();
for (int i=0; i<COUNT; i++) {
  OS.pango_layout_set_text(layout, new byte[]{'a','b','c','d','e'}, 5);
  int[] width = new int[1], height = new int[1];
  OS.pango_layout_get_size(data.layout, width, height);
  OS.pango_layout_set_text(layout, new byte[]{'f','g','h','i','j'}, 5);
  OS.pango_layout_get_size(data.layout, width, height);
}
System.out.println (msg + " stringExtent() - count=" + COUNT + "time=" +
(System.currentTimeMillis() + time) + " ms");

in C?  You can probably get a GTK app up and running faster than me that initializes pango and then does the set text (as above) followed by get_size.  Those numbers may help too.
Comment 81 Behdad Esfahbod CLA 2007-01-04 17:34:55 EST
(In reply to comment #78)
> I'll look into the profiler, it may help, but for now I have isolated a few
> lines that seem to be causing some of the slowness (at least on the text extent
> part).

Thanks.

> time = -System.currentTimeMillis();
> for (int i=0; i<COUNT; i++) {
>   OS.pango_layout_set_text(layout, new byte[]{'a','b','c','d','e'}, 5);
>   int[] width = new int[1], height = new int[1];
>   OS.pango_layout_get_size(data.layout, width, height);
>   OS.pango_layout_set_text(layout, new byte[]{'f','g','h','i','j'}, 5);
>   OS.pango_layout_get_size(data.layout, width, height);
> }
> System.out.println (msg + " stringExtent() - count=" + COUNT + "time=" +
> (System.currentTimeMillis() + time) + " ms");
> 
> This takes about 5 seconds for 100,000 iterations.
> The OS.* simply call the native methods with the same name.  This is
> (basically) the way SWT is using Pango to calculate text extents.  It is much
> faster if you don't change the text during each iteration, but I don't think
> that is realistic. 

Right.  However, a extent calculation plus a rendering has become a lot cheaper in Pango 1.15.2.  That is, none of the two become much faster, but if you do both, one is almost free now.

I'm also curious in how you are measuring it on Windows (as in, the equivalent of the above code).

> If GTK is < 2.8 it uses:
> 
> cairo_font_extents_t font_extents = new cairo_font_extents_t();
> Cairo.cairo_font_extents(cairo, font_extents);
> cairo_text_extents_t extents = new cairo_text_extents_t();
> Cairo.cairo_text_extents(cairo, buffer, extents);

This is totally broken for everything other than ASCII, but doesn't really matter I guess.
Comment 82 Felipe Heidrich CLA 2007-01-04 18:01:37 EST
Hello Andrew, I believe the problem you have is not your fault but a bug in SWT. Grant, do you still have a 64bit linux machine ? Can you try the benchmark there ?

Ian & Behdad: when you use advance graphics in SWT you are really using a different technology. For example, on windows it uses GDI for normal mode and GDI+ for advance mode. On GTK it uses GDK for normal mode and Cairo for advance mode. The application should set advance mode when it needs to use 'advance' features like transform or alpha.

Ian: Usually if you compare SWT PI code versus native C code you are really going to measure the time SWT waste to cross the JNI layer. In past benchmarks this number was close to zero.
Comment 83 Ian Bull CLA 2007-01-04 18:17:59 EST
(In reply to comment #82)
> Ian & Behdad: when you use advance graphics in SWT you are really using a
> different technology. For example, on windows it uses GDI for normal mode and
> GDI+ for advance mode. On GTK it uses GDK for normal mode and Cairo for advance
> mode. The application should set advance mode when it needs to use 'advance'
> features like transform or alpha.

Thanks Felipe, that is why I was confused about advanced graphics.  I have used SWT advanced graphics for other operations, but it seems that SWT (GTK version at least) handles text rendering differently when Advanced is set to true.  It seems to run faster, and according to Behdad (who knows a lot more about this than I ever will) the non-advanced way is not optimal. 

> Ian: Usually if you compare SWT PI code versus native C code you are really
> going to measure the time SWT waste to cross the JNI layer. In past benchmarks
> this number was close to zero.
> 
Figured as much.  I was just hoping that by creating a C version with similar time measurements, the Pango guys may be able to tell us if we are using Pango correctly (especially now that they have done improvements in caching).

Thanks for the tips Felipe. Any help here is greatly appreciated :)
Comment 84 Ian Bull CLA 2007-01-04 18:37:26 EST
(In reply to comment #81)
> Right.  However, a extent calculation plus a rendering has become a lot cheaper
> in Pango 1.15.2.  That is, none of the two become much faster, but if you do
> both, one is almost free now.
Makes sense. However, I would assume that if I just rendered the same text continually it should be fast then.  But even the following code takes > 5 seconds:

for (int i=0; i<COUNT; i++) {
  Cairo.cairo_move_to(cairo, 10, 50);
  OS.pango_cairo_show_layout(cairo, data.layout);
  Cairo.cairo_move_to(cairo, 10, 150);
  OS.pango_cairo_show_layout(cairo, data.layout);
}

(Note: I just move the location and draw the same text ("Hello") repeatedly) 
 
> I'm also curious in how you are measuring it on Windows (as in, the equivalent
> of the above code).

Not sure exactly, but the benchmark basically moves the cursor, sets the text to "Hello" and renders it, then it moves the cursor, sets the text to "There" and renders it.  It repeats this 100,000 times.  I don't know if caching works here since the text continuously changes.

Then the benchmark does the same thing, but instead of rendering the text it just gets the extents.  Again the text continually changes.

I hope this helps, and thanks for following this Behdad!
Comment 85 Felipe Heidrich CLA 2007-01-04 18:53:13 EST
> I'm also curious in how you are measuring it on Windows (as in, the equivalent
> of the above code).

In normal mode:
OS.GetTextExtentPoint32W(handle, buffer, length, size);
In advance mode:
int format = Gdip.StringFormat_Clone(Gdip.StringFormat_GenericTypographic());
Gdip.StringFormat_SetFormatFlags(format, Gdip.StringFormat_GetFormatFlags(format) | Gdip.StringFormatFlagsMeasureTrailingSpaces);
Gdip.Graphics_MeasureString(data.gdipGraphics, buffer, buffer.length, data.gdipFont, pt, format, bounds);
Gdip.StringFormat_delete(format);

GTK has more code running really, you need to create a pangolayout before you can measure anything.
Comment 86 Felipe Heidrich CLA 2007-01-04 18:58:37 EST
Andrew: Please make sure you are running the 64bits version of SWT on your 64bits machine. In the download page look for Linux (x86_64/GTK 2). Personally I would run in a 32bits machine like everyone else in the problem report.
Comment 87 Felipe Heidrich CLA 2007-01-04 19:06:27 EST
> This is not optimal, to say the least.  No idea why a temp pixmap is used.

This code is doing XOR, the normal case it is only a call to:
gdk_draw_layout_with_colors()
Comment 88 Ian Bull CLA 2007-01-04 19:09:27 EST
(In reply to comment #87)
> > This is not optimal, to say the least.  No idea why a temp pixmap is used.
> 
> This code is doing XOR, the normal case it is only a call to:
> gdk_draw_layout_with_colors()
> 
Sorry about that guys... I didn't see that if statement.  That was my fault :(
Comment 89 Andrew Overholt CLA 2007-01-05 09:19:11 EST
(In reply to comment #86)
> Andrew: Please make sure you are running the 64bits version of SWT on your
> 64bits machine.

I am.  I eventually got it working by pointing LD_LIBRARY_PATH (it also worked with java.library.path) to the exploded 64-bit JNI .sos.

My times were similar to Ian's.  Behdad was working on an equivalent benchmark in C to compare.  I think he'll have further comments.
Comment 90 Andre Weinand CLA 2007-01-05 18:26:02 EST
Re comment #63:

Windows Vista Business
running inside Parallels Desktop for Mac
Build 3106 Beta 3 (28. Dezember 2006)
on
MacBook Pro  Intel Core 2 Duo 2.33 GHz
Mac OS X 10.4.8 (8N1037)
L2 Cache (shared): 4 MB
Memory: 3 GB
Bus Speed: 667 MHz

java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

Control drawString() - count=100000 time=2894 ms
Control stringExtent() - count=100000 time=701 ms
Image drawString() - count=100000 time=1883 ms
Image stringExtent() - count=100000 time=211 ms
Comment 91 Andre Weinand CLA 2007-01-05 18:27:56 EST
Oops, my comment #90 is a response to Felipe's comment #73, not comment #63.
Comment 92 Kevin Barnes CLA 2007-01-07 16:01:35 EST
Hardware:
  Processor: Intel Core 2 Duo 2.16 GHz
  L2 Cache:	4 MB
  Memory:	2 GB
  Bus Speed:	667 MHz

Mac OS X 10.4.8
Control drawString() - count=100000 time=6661 ms
Control stringExtent() - count=100000 time=3882 ms
Image drawString() - count=100000 time=5150 ms
Image stringExtent() - count=100000 time=3952 ms


Windows Vista (Parallels)
Control drawString() - count=100000 time=2464 ms
Control stringExtent() - count=100000 time=491 ms
Image drawString() - count=100000 time=2103 ms
Image stringExtent() - count=100000 time=392 ms



Comment 93 Kevin Barnes CLA 2007-01-07 16:08:18 EST
Fedora Core 6 running in Parallels - See comment 92 for hardware

Control drawString() - count=100000 time=2464 ms
Control stringExtent() - count=100000 time=491 ms
Image drawString() - count=100000 time=2103 ms
Image stringExtent() - count=100000 time=392 ms
Comment 94 Kevin Barnes CLA 2007-01-07 16:11:34 EST
Comment 93 is wrong, I pasted the Vista numbers again.

Fedora numbers are:
Control drawString() - count=100000 time=19881 ms
Control stringExtent() - count=100000 time=5758 ms
Image drawString() - count=100000 time=16635 ms
Image stringExtent() - count=100000 time=6232 ms
Comment 95 Mike Wilson CLA 2007-01-08 09:53:39 EST
One of the things I noticed when configuring my wife's new laptop was that turning on ClearType caused the string benchmark to be 3..4 times slower. Are people running their XP tests with ClearType on or off?
Comment 96 Scott Kovatch CLA 2007-01-08 11:41:06 EST
Mike raises a good point in #95 that reminds me of a problem we ran into with benchmarks and the Mac AWT. On the Mac, text is drawn aliased by default where on Windows (and, by extension, the AWT) it's antialiased by default. Comment #56 notes this difference on Linux as well. As a result we get clobbered in text benchmarks. Andre, can you try with and without the antialiasing to compare?
Comment 97 Steve Northover CLA 2007-01-08 12:02:04 EST
Quite true, however, anti-alias should not affect measuring.  I suspect that Windows is highly optimized for English and the other platforms are not.  We should test this theory by benching a Bidi or Japanese string.  Does Windows start sucking or draw the text wrong?
Comment 98 Andre Weinand CLA 2007-01-08 12:09:17 EST
Re #96: turning off antialiasing does not have the expected effect:

antialiasing off:
Control drawString() - count=100000 time=6015 ms
Control stringExtent() - count=100000 time=3556 ms
Image drawString() - count=100000 time=5082 ms
Image stringExtent() - count=100000 time=3595 ms

antialiasing on:
Control drawString() - count=100000 time=6063 ms
Control stringExtent() - count=100000 time=3556 ms
Image drawString() - count=100000 time=4657 ms
Image stringExtent() - count=100000 time=3589 ms
Comment 99 Ian Bull CLA 2007-01-08 12:41:13 EST
(In reply to comment #82)
> Hello Andrew, I believe the problem you have is not your fault but a bug in
> SWT. Grant, do you still have a 64bit linux machine ? Can you try the benchmark
> there ?
> 
Felipe, Steve, Grant....
Do you know if this issue has been looked at?  Is this related to not extracting the library file from the Jar?  Would you like me to reopen Bug #166865 (or create another bug).  I don't think this is related to the benchmark, I just don't want this issue to get lost in the mix.
Comment 100 Steve Northover CLA 2007-01-08 13:30:55 EST
Please create a new bug.
Comment 101 Ian Bull CLA 2007-01-08 13:41:41 EST
(In reply to comment #100)
> Please create a new bug.
> 
Done:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=169875
Comment 102 Behdad Esfahbod CLA 2007-01-08 22:21:15 EST
So yeah, Andrew and I did some testing.  And I did the extents test in C too.  Seems like, using Hotspot, one-third of the extent measurement from Java is spent in the Java layer.  With natively compiled CLASSPATH it became half the time.

I profiled the C example.  It's not very easy to optimize it drastically. 50% of the time is being spent in the OpenType shaper.  I'm doing a rewrite of that code, that may or may not make it faster.  I can go on and make it fast, at the expense of more memory use, but my current feeling is that we shouldn't need to do that.

Anyway, good point raised about ClearType.  Any comparison to non-ClearType rendering is Apples and Oranges (pun intended ;) ).
Comment 103 Eclipse Webmaster CLA 2019-09-06 16:07:25 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.
Comment 104 Alexander Kurtakov CLA 2019-10-10 16:54:36 EDT
This is ancient and contians so much data that it's hard for me to even find out what/if anything is still pending there. Close.