On Mon, Oct 1, 2012 at 12:37 AM, F.S. <
speec...@gmail.com> wrote:
> I don't seem to observe the visible slowing from syntax coloring when editing large emacs or vim buffers. I am trying to understand why Leo has such a significant degradation in performance.
Many thanks for your questions. The association of colorizing with
(file) caching has lead my thoughts in new directions. As I shall
explain, there is no obvious way to speed up Leo's syntax colorizing,
but perhaps the solution to a seemingly intractable problem can be
found...
Leo is different from emacs or vim because Leo recolors the entire
text every time Leo selects a node. In contrast, emacs or vim selects
a buffer once, when loading the file. In fact, Leo does a good job of
incremental coloring, even for very large nodes. In this sense, the
difference in performance could be said to be a difference in
perception.
As the result of your previous questions, I have been investigating
caching syntax-coloring data. Unlike Tk, Qt does not provide an
efficient way of reporting such data: QSyntaxHighlighter.format(n)
only reports on the formatting of the *single* character at position
n. This call returns a *different* instance of QTextCharFormat for
every character in the body text, even if the formats for two
characters are identical.
Actually, there *is* an effective way of caching data: associate a
*separate* instance of QSyntaxHighlighter with every node(!) Taking
this idea a step farther, we could even imagine a separate instance of
QTextBrowser for every node(!!) This last step is almost certainly a
step too far.
But even just creating per-node copies of QSyntaxHighlighter would be
a big memory drain. Presumably, QSyntaxHighlighter contains an
instance of QTextCharFormat for every character in the body text, and
other formatting data as well. Retaining that data for each node would
probably overburden the GC. Although an intriguing idea, creating a
separate instance of QSyntaxHighlighter for each node seems too risky.
So it looks like we need something that QSyntaxHighlighter does not
provide, namely a summary of the formatting in effect when we leave a
node. If we had such a summary, Leo would be able to recolor
previously colored nodes *quickly* when revisiting the node. Such a
scheme would not be a memory buster provided that summaries were
concise.
Using QSyntaxHighlighter.format(n) to compute the summary data when
Leo leaves a node is probably going to be too slow. Because format(n)
returns a separate instance of QTextCharFormat for each character,
just determining whether adjacent characters are formatted alike may
be expensive. I experiment asap...
Could Leo's syntax coloring code create the *concise* summary data?
jEditColorizer.setTag is the obvious place. Alas, computing the
summary data seems very difficult. Character indices change as the
user inserts or deletes characters, so creating a concise summary of
the ranges of characters colored in any particular style appears to
require major computation. It's a puzzle with no obvious solution...
The conclusion is simple: without a fast, memory efficient way of
summarizing the entire state of syntax coloring in a node, Leo must
recolor a node whenever Leo selects it. This is the big difference
between Leo and emacs/vim.
Edward