Bug 25467 - Accelerator Menu performance problems (GTK & Motif)
Summary: Accelerator Menu performance problems (GTK & Motif)
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 2.1   Edit
Hardware: PC Windows 2000
: P1 critical (vote)
Target Milestone: ---   Edit
Assignee: Chris McLaren CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 25777 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-10-28 15:24 EST by Chris McLaren CLA
Modified: 2002-11-13 10:37 EST (History)
6 users (show)

See Also:


Attachments
The benchmark code (6.05 KB, text/plain)
2002-10-30 16:04 EST, Steve Northover CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chris McLaren CLA 2002-10-28 15:24:44 EST
GTK and Motif have significant performance problems using the hidden menu in 
its current form. I looked at a profile and found that at least 700ms is spent 
in AcceleratorMenu.setAccelerators on these platforms (every time we 
recalculate the menu - which can be as often as switching editors). I am hoping 
that this has to do with the fact that the hidden menu is being disposed of and 
recreated with new menu items each time setAccelerators is called. Can someone 
look at this, and perhaps reuse MenuItem instances if that proves to be the 
problem?
Comment 1 Steve Northover CLA 2002-10-29 11:02:29 EST
This is a P1.  Chris to assist SN constructing a benchmark.
Comment 2 Steve Northover CLA 2002-10-30 16:04:57 EST
Created attachment 2292 [details]
The benchmark code
Comment 3 Steve Northover CLA 2002-10-30 16:36:22 EST
Results:

Windows 98, PII-433-256 - 110ms
Motif RedHat PII-450-256 - 438ms
GTK RedHat 8.0 PIII-500-512 - 180ms

These times don't look that bad, given the machines I am running on.  Do you 
want me to investigate further?  Is it possible that the UI code is calling 
this API multiple times instead of just once when switching between editors?
Comment 4 Mike Wilson CLA 2002-11-01 15:52:42 EST
If that benchmark really is indicative of the problem, then Motif should be taking even 
longer to switch pages than GTK. Thus either the benchmark isn't a good indicator, or the 
problem is somewhere else. We need to find out which of these is true.

This is still P1 in SWT. If SN isn't going to do the work to figure out what's going on, he 
should assign it to UI so they can find someone to do it.
Comment 5 Steve Northover CLA 2002-11-01 17:49:36 EST
I can't really look at this now.  Here's what I suspect.

I believe that the problem is that UI does a whole bunch of work on 
Acivate/Deactivate.  This happens on GTK when a menu loses focus.  It didn't 
use to happen (we had code that avoided this in Menu) but the code was a mess 
and introduced bugs.  Taking it out fixed bugs.

We can put the code back if necessary.  UI needs to confirm that they are 
calling this API only once when switching editors.
Comment 6 Veronika Irvine CLA 2002-11-09 12:23:10 EST
We investigated the performance problem and found that
AcceleratorMenu.setAccelerators was being called repeatedly with the same list
of accelerators.  The proposed fix is to check for the case where the lists are
the same and do nothing.  Below is a modified version of setAccelerator which
does this.  There are benchmark checks included as well.  With this fix, calling
setAccelerator when the items are the same takes less than a millisecond.  When
switching between Java editors, the list is always the same.  Also, there was a
null problem in the code which I fixed:


//benchmarking
int count = 0;
//
public void setAccelerators(final int[] accelerators) {
	//benchmarking
	long start = System.currentTimeMillis();
	//
	if (accelerators == null) {
		this.accelerators = null;
	} else {
		if (this.accelerators != null && this.accelerators.length ==
accelerators.length){
			int index = 0;
			if (accelerators.length > 0) {
				while (index < accelerators.length) {
					if (this.accelerators[index] != accelerators[index]){
						break;
					}
					index++;
				}
			}
			if (index == accelerators.length){
				//benchmarking
				long end = System.currentTimeMillis();
				count++;
				System.out.println(count + "setAccelerators - no change");
				System.out.println(count +"setAccelerators time = "+(end - start));
				//
				return;
			}
		}
		this.accelerators = new int[accelerators.length];
		System.arraycopy(accelerators, 0, this.accelerators, 0, accelerators.length);
	}
	
	menu.dispose();
	menu = new Menu(parent.getParent(), SWT.DROP_DOWN);
	if (item != null) item.setMenu (menu);
	
	if (accelerators != null) {
		for (int i = 0; i < accelerators.length; i++) {
			final int key = accelerators[i];
			MenuItem keyMenuItem = new MenuItem(menu, SWT.PUSH);
			keyMenuItem.setAccelerator(key);
			keyMenuItem.addListener(SWT.Selection, menuItemListener);
		}
	}
	//benchmarking
	long end = System.currentTimeMillis();
	count++;
	System.out.println(count + "setAccelerators length = "+((this.accelerators ==
null) ? 0 : this.accelerators.length));
	System.out.println(count +"setAccelerators time = "+(end - start));
	//
}
Comment 7 Andrew Irvine CLA 2002-11-09 12:31:14 EST
The UI team will need to investigate the six calls.  Shall we track this under 
the same PR or a different one?  Added Nick to the CC
Comment 8 Nick Edgar CLA 2002-11-09 13:03:06 EST
Reassigning to UI to investigate the 6 calls, and apply the changes above if 
they haven't been already.
Comment 9 Tod Creasey CLA 2002-11-11 16:50:17 EST
*** Bug 25777 has been marked as a duplicate of this bug. ***
Comment 10 Chris McLaren CLA 2002-11-13 10:37:53 EST
added this line to the beginning of setAccelerators(..) method:
if (java.util.Arrays.equals(this.accelerators, accelerators)) return;

committed to head nov 13 10:35am

regarding 6 calls: will investigate in workbench, but performance issues should 
largely disappear. another performance issue was already addressed 
(preoptimizing keybindings for platform and locale), and further specific 
optimizations in the keybinding engine will be committed shortly.