Re: Optimizing text layout in a log view: should I subclass NSLayoutManager?
Re: Optimizing text layout in a log view: should I subclass NSLayoutManager?
- Subject: Re: Optimizing text layout in a log view: should I subclass NSLayoutManager?
- From: Camillo Lugaresi <email@hidden>
- Date: Thu, 9 Feb 2006 22:44:47 +0100
On 07/feb/06, at 00:38, Douglas Davidson wrote:
On Jan 24, 2006, at 5:22 AM, Camillo Lugaresi wrote:
The problem is that deleting lines at the top invalidates the
layout for the entire text view, which makes things slow for long
logs, and in general causes undesirable CPU usage. I will
implement the obvious fix of deleting lines less often (eg let the
buffer grow to 1.1 times the desired maximum, and then clip off
the extra 10% in one fell swoop). However, I'd like to solve this
problem more radically.
Clearly, when deleting whole lines at the top, the layout of the
rest of the text does not really need to be recalculated: it
should be sufficient to cache an offset from the old line
positions, and add it to the stored information whenever it is
requested (the line that was at ordinate 30 is now at 30-14, etc.).
My question is: is it possible and desirable to add such an
optimization by subclassing NSTextLayout, or in some other way? It
is unclear to me if that class is designed for subclassing, and to
what extent; before pursuing this solution, I would like to know
if it is a recommended approach or if I should instead write a
fully custom text view that does not use the Cocoa text system.
As it happens, NSLayoutManager already has an optimized relayout
algorithm for this sort of case. The conditions under which it can
be used are a little complicated, however, so what I would
recommend as a first step would be sampling the application under
conditions where it behaves badly, to see where the time is
actually being spent. That should tell you, among other things,
whether layout is actually the issue, and whether you are falling
off the optimized code path or not.
Thanks for your reply. I have sampled my test application using
Shark. It has a text view with a relatively large amount of styled
text (3000 lines), and a timer that adds a line at the bottom and
removes one at the top every 0.5 seconds, to simulate a steady flow
of incoming messages. This consumes over 20% of the CPU time on a 1.8
GHz G5 as long as the timer is running: clearly unacceptable. If
lines are only added at the bottom and not removed from the top, CPU
usage drops below 3% (which is still a lot, but there is probably
some more room for optimization).
Some data from Shark:
- the timer which adds and removes lines accounts for slightly less
than 20% of the application's time; appending to the text storage
takes 8%, removing takes 10%;
- 56% of the time is spent doing layout in the background, which
involves these methods:
0.1% 56.0% AppKit +[NSLayoutManager(NSPrivate)
_doSomeBackgroundLayout]
0.0% 55.7% AppKit -[NSLayoutManager(NSPrivate)
_fillLayoutHoleAtIndex:desiredNumberOfLines:]
0.1% 23.4% AppKit -[NSLayoutManager invalidateDisplayForGlyphRange:]
0.0% 22.4% AppKit -[NSATSTypesetter
layoutGlyphsInLayoutManager:startingAtGlyphIndex:maxNumberOfLineFragment
s:nextGlyphIndex:]
2.3% 6.5% AppKit -[NSLayoutManager(NSPrivate)
_doOptimizedLayoutStartingAtGlyphIndex:forSoftLayoutHole:inTextContainer
:lineLimit:nextGlyphIndex:]
It seems to be taking an optimized path, but I am not sure if it is
the one you mentioned.
- finally, 15.5% of the times is used to update the display.
What do you think? Is this the best performance I can get out of the
standard text system, or are there some optimizations that I am missing?
Camillo
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden