From: John_Miller@mindlink.bc.ca (John Miller)
Subject: re: Tabbing Speed (long)
Organization: MIND LINK! - British Columbia, Canada
Date: Fri, 6 Nov 1992 22:36:05 GMT

In article <a71de956@random.se>, ianf@random.se (Ian Feldman) writes
> Peter Fleck asks
>-----------------
>
>> I'm looking for tricks to speed up tabbing through fields on a
>> card.  With no enhancements, it takes 4 SECONDS to move from one
>> field to another on a Classic II running System 7 (maybe 7.1, not
>> sure) (HyperCard v2.1).  With the external FastTab (v1.01, is that
>> the latest?) installed, the tab speed is halved (2 seconds).  Any
>> suggestions on further increasing tabbing speed? Any other
>> externals available -- including commercial stuff.
>
>> Is tabbing speed affected by the number of fields on a background
>> or card?
>  yes, tabbing speed is definitely affected by the number of fields
>  -- whether card or background doesn't matter much.  The more there
>  are of them, the longer it will take for the HC to close current/
>  open new internal buffers that it has to maintain for each
>  activated field (remember the undo!).  The more the memory is
>  fragmented, the longer it will take for the OS to find and
>  allocate space for such buffers.  FastTab 1.0.1 XCMD by John
>  Miller works around this problem and is thus able to halve the
>  times for tabbing among fields.

I don't think internal buffers and undo have too much to
do with HyperCard's tabbing speed problem.  I would guess
that HyperCard would use a single set of buffers for a
global undo for all fields.  Remember also that undo
handles the changes since the last text selection.  At
least this is the standard Mac behaviour:  I believe
HypCard 2.x does this while HypCard 1.x.x based Undo
on any changes since that field was first selected until
you moved out of that field.  HyperCard 2.x does not
have a speed problem when clicking with the current
field.

What is causing the problem is that HyperCard redraws
every field whenever the user presses the Tab key.  Some
of the time is spent on calls to the ToolBox to redraw
each field and the rest of the time is spent on all the
things HyperCard must handle in order to get the field
ready for drawing:  saving/restoring the clip region,
establishing the clip region for the field, moving the
(I believe one shared) TextEdit record and assigning
the text to it.

Unfortunately, except for a brief paragraph on the
Example Card, the FastTab documentation stack does not
discuss what issues affect the obtainable speedup.
FastTab works by tricking HyperCard into not redrawing
unnecessary fields.  Fields are treated as an atomic
unit:  if a field has to be redrawn, the entire field
is redrawn.  Also, FastTab makes no attempt to speed
up the actual field drawing:  if a field has to be redrawn
then the drawing speed is the same as for untricked
HyperCard.  The fields that will be redrawn are
1) The field that had text selected
2) The field with the newly selected text
3) Any fields that overlap the old and new fields
4) Any fields that overlap the overlapping fields.  This
rule is applied recursively, although it is possible
for an unusual field arrangement to fool FastTab.

This means that FastTab provides the greatest speedup
for cards containing lots of small non-overlapping fields.
The speedup for cards that contain a small number of
large multi-line fields will be a much less: the number
of fields drawn represents a higher percentage of
the total number and each of these fields take
longer to display than small fields.

For a stack that takes 4 seconds to tab on a Classic II,
all the timing tests I have done and the feedback I have
received suggests that the speedup should be at least
5 times.  Possible reasons that the tabbing time was only
halved in this case are:
1) The stack contains many large fields, in which case
the previous paragraph explains.
2) One thing that has trapped several users is the use
of a "backdrop" field behind other fields.  A backdrop
can give an nice shadow grouping to the card layout,
but it means that the overlap fields come into play:
whenever one of the fields in that section of the card
have to redrawn, they all have to be redrawn.  If a
single backdrop field encompasses every other field on
the card, then every field is redrawn and FastTab
is even slower than standard HyperCard tabbing.
3) Perhaps the field are arranged in some other
highly overlapping arrangement.

[In correspondence with the original author of the stack,
he indicated that some of the fields were locked
"label" fields, such as Apple used in the Address stack.
This increases the number of fields, so it should improve
the speedup generated by FastTab, but I would guess that
even better speed would be seen by Mr. Fleck's
decision to convert these labels to paint text.]

[...]

>  what to do.  Despair not: it _IS_ actually possible to TAB to,
>  enter and modify contents of any particular field at nearly-
>  instantaneous speeds even on the slowest of Macs.

No, it's not, but the technique you discuss of using a single
field while scripting tricks create the illusion of separate
fields is an alternate solution to the speed problem.  With my
limited attempts at this approach, I have found it difficult
to maintain the illusion adequately through all possible
user actions -- typing, mousing, cutting/pasting, particularly
if some "fields" in the grid represent calculated values -- but I
suspect that with enough scripting, a suitable illusion could
be created.

One thing I find hinders this approach was the change
in openField behaviour between HyperCard 1.2.5 and HypCard 2.x.
HyperCard 1.2.5 would send an openField every time the
mouse is clicked in a field, while HyperCard 2.0 changed this
so that an openField is not sent if the user clicks/drags
in another part of the currently selected field.  I prefer
the old approach: it also makes it easier to do non-standard
things like using single-clicking to select a word.

> Believe me, it can be done...  I've done it and can report that
> thus-simulated "tabbing" speeds were 1/4th to 1/2 of those
> achievable with the help of the FastTab XCMD employed on the SAME
> COMPOUND MULTI-LINE field.

This is something that the FastTab documentation stack
unfortunately does not discuss.  If you are selecting text
with the currently "active" field, FastTab cannot speed
anything up.  The good news is that the standard HyperCard
"select" command does not have a speed problem when selecting
text in the current field.  The speed problem only comes when
selecting text in a different field (either by tabbing, mousing,
or using the "select" command).

So in your design, FastTab can provide no speedup.  It will
be slower because
1) there is the overhead of loading and invoking the XCMD
2) the XCMD has its own execution overhead
3) in the HyperTalk script, the "select" command is translated
to machine code once, when the script is compiled.  If you
use FastTab, HyperCard has to translate the select command
every time it is invoked.  This adds some overhead.  [This
is one reason that *some* HyperTalk scripts run slower
when compiled with CompileIt.]


> That's right, interpreted HyperTalk
> alone is often faster than an external, compiled command resource.

Well, I have now reached the quibble stage, but the accurate
comparision is between this compiled command resource and
the unaided use of a built-in HyperCard primitive, a primitive
that is already plenty fast enough when used as you described.
While FastTab is able to speed things up -- under
certains conditions -- it does not fit into the traditional
speed-based discussion of XCMD versus HyperTalk.

John Miller
Symplex Systems