[comp.windows.x.motif] MOTIF 1.1.0 Bug - Performance

marcs@SLC.COM (Marc San Soucie) (12/12/90)

                          OSF Problem Report
                  =================================

Submitter Information (Include Email address at miminum)
---------------------

Submitter Name:         Marc San Soucie
Organization:           Servio Corporation - Beaverton, Oregon
Email Address:          marcs@slc.com
Phone:                  503-690-3526
OSF License Number:     Could be 287

Hardware/Software Configuration
-------------------------------

Offering and Version:   Motif 1.1.0
Component (Module):	VirtKeys.c
Client Hardware:        Sun SPARCStation 1, 16Meg memory
Client Software:        SunOS 4.0.3, X11R4 (MIT)
Server Hardware:        SAME
Server Software:        SAME
Compiler:               ?

Problem Description
-------------------

Severity Level: Severe

    Because I find this kind of thing hard to swallow...


Date of First Occurrence:

    12/10/90

One Line Description:

    FindVirtKey is excessively slow, and is called too many times.


Full Description:

    I was running 'prof' against a bunch of MOTIF applications built with prof
    version of libXm.a, libXt.a, and libX11.a, in order to see where all the
    time was going. In this particular case, I was running a complex multi-pane
    EMACS-like editor thing which included a pair of multi-line text widgets. I
    created widget hierarchies, created text buffers, moved the focus around,
    pulled down some menus, and typed about 140 keystrokes. Here are the top
    few lines of the 'prof' output, which YES, I KNOW is not overwhelmingly
    accurate, but it does give some idea of the problem.

    First, it is simply unfathomable that FindVirtKey should need to be called
    47000 times to handle 140 keystrokes. Not having studied the
    interrelationship between XtTranslateKeycode and XmTranslateKey in detail,
    I can only surmise that someone has written a blunt and clumsy loop when a
    modicum of smarts would have been more effective.

    Second, FindVirtKey itself is written in such a way as to insure its place
    high on the list of costly calls. I have supplied a suggestion for its
    improvement below. The improved version is unfortunately only 20-30%
    faster, since the bulk of the problem is that MOTIF is walking through a
    longish virtual bindings list a gobule of times for easy lousy keystroke.

    Add up all the costs due to virtual keysym lookup and you've got one heck
    of a CPU-expensive widget set there.


    %time  cumsecs  #call  ms/call  name
    30.9     3.61  47063     0.08  _FindVirtKey
    11.0     4.89                  mcount
     2.7     5.21  47063     0.01  _XtTranslateKey
     2.4     5.49   9682     0.03  _XrmStringToQuark
     2.2     5.75  46644     0.01  __XtConvertCase
     2.0     5.98  91405     0.00  multiply.o
     1.8     6.19   9295     0.02  __XtMatchUsingDontCareMods
     1.7     6.39    304     0.66  _RefigureLines
     1.7     6.59   1013     0.20  _read
     1.6     6.78  47063     0.00  _XtTranslateKeycode
     1.5     6.96   3662     0.05  _ComputeLateBindings
     1.5     7.14    192     0.94  _XStringToKeysym
     1.5     7.31    679     0.25  select.o
     1.4     7.47    292     0.55  write.o
     1.3     7.62  50350     0.00  _XFindContext
     1.1     7.75    680     0.19  _FindWidth
     1.1     7.88                  _HPfree
     1.1     8.01  47063     0.00  __XmTranslateKey
     1.0     8.13                  hpalloc.o
     1.0     8.25    157     0.76  writev.o
     0.9     8.36                  iss2
     0.9     8.46     33     3.03  _access
     0.9     8.56   2000     0.05  ioctl.o
     0.8     8.65    703     0.13  SetValues.o
     0.7     8.73   7777     0.01  _MeasureLine
     0.7     8.81  13699     0.01  __XmGetClassExtensionPtr
     0.7     8.89  11765     0.01  __XmIsSlowSubclass
     0.6     8.96   1120     0.06  _Scan
     0.6     9.03                  w4cp
     0.5     9.09   2873     0.02  _CallSetValues
     0.5     9.15   1524     0.04  gettimeofday.o
     0.4     9.20    512     0.10  _MatchEvent
     0.4     9.25    155     0.32  __XmTextInvalidate
     0.4     9.30                  w4cp
     0.3     9.34     60     0.67  _BindActions
     0.3     9.38  15138     0.00  _EqualEvents
     0.3     9.42  47326     0.00  _GetVirtualBindingsData
     0.3     9.46   1135     0.04  _ScanAlphanumeric
     0.3     9.50    845     0.05  _XNextEvent
     0.3     9.54    846     0.05  _XtAppNextEvent


Repeat By:

    Build a 'prof' version of anything with a multi-line text widget in it. Or
    any widget, for that matter, that accepts keystrokes.


Proposed Solution:


static void FindVirtKey (virtData, keycode, modifiers,
			 modifiers_return, keysym_return)

XmVirtualBindingsData	virtData;
KeyCode			keycode;
Modifiers		modifiers;
Modifiers		*modifiers_return;
KeySym 			*keysym_return;

{
    XmKeyBinding	keyBindings = virtData->bindings;
    Cardinal		i;
    XmKeyBinding	currBinding;
    Modifiers		eventMods;
    KeySym		keysym;

    /*
     * get the modifiers from the actual event
     */
    eventMods = (Modifiers)(virtData->lastKeyEvent->state) & modifiers;

    keysym = *keysym_return;
    currBinding = keyBindings;
    for (i = 0; i < XtNumber(virtualKeysyms); i++)
	{
	/*
	 * the null binding should not be interpreted as a match
	 * keysym is zero (e.g. pre-edit terminator)
	 */
	if (currBinding->keysym == keysym &&
	    currBinding->modifiers == eventMods &&
	    currBinding->keysym)
	    {
	    *keysym_return = virtualKeysyms[i].keysym;
	    break;
	    }

        currBinding++;
	}

    *modifiers_return |= ControlMask | Mod1Mask;
}


New numbers for approximately the same activity...
Better, but not great. Solve the real problem, and throw this in for the fun of
it.


    %time  cumsecs  #call  ms/call  name
    20.6     2.20  47419     0.05  _FindVirtKey
    14.1     3.71                  mcount
     3.5     4.08   3694     0.10  _ComputeLateBindings
     2.8     4.38  47419     0.01  _XtTranslateKey
     2.5     4.65   1011     0.27  select.o
     2.2     4.89   9773     0.02  _XrmStringToQuark
     2.2     5.12    311     0.74  _RefigureLines
     2.2     5.35   9366     0.02  __XtMatchUsingDontCareMods
     2.0     5.56    192     1.09  _XStringToKeysym
     2.0     5.77   1184     0.18  _read
     1.9     5.97  47419     0.00  _XtTranslateKeycode
     1.7     6.15  47000     0.00  __XtConvertCase
     1.7     6.33    384     0.47  write.o
     1.6     6.50  50863     0.00  _XFindContext
     1.6     6.67                  hpalloc.o
     1.5     6.83    160     1.00  writev.o
     1.3     6.97  47419     0.00  __XmTranslateKey
     1.2     7.10                  _HPfree
     1.1     7.22  92234     0.00  multiply.o
     0.9     7.32    690     0.14  _FindWidth
     0.8     7.41    321     0.28  _GetResources
     0.8     7.50  47684     0.00  _GetVirtualBindingsData
     0.8     7.59     33     2.73  _access
     0.7     7.67   7873     0.01  _MeasureLine
     0.7     7.75  14482     0.01  __XmGetClassExtensionPtr
     0.7     7.83   2148     0.04  gettimeofday.o
     0.7     7.91                  w4cp
     0.7     7.98    774     0.09  _ImportArgs
     0.7     8.05    603     0.12  _MatchEvent
     0.7     8.12   2787     0.03  ioctl.o
     0.6     8.18   1140     0.05  _Scan
     0.5     8.23    733     0.07  SetValues.o
     0.5     8.28   7732     0.01  _AddRedraw
     0.5     8.33   1829     0.03  _CallGetValuesHook
     0.5     8.38   2964     0.02  _CallSetValues
     0.5     8.43  12504     0.00  __XmIsSlowSubclass