useless calls to layout lines

Milian Wolff mail at milianw.de
Fri Mar 23 21:24:21 UTC 2018


Hey all,

https://phabricator.kde.org/D11487 got me interested in the performance of 
Katepart for long lines again. The culprit on my machine really is line 
layouting - which shouldn't come as a surprise if the line is really long.

But what *does* surprise me is the amount of layouting we do. The five lines 
in the document get layouted ~40 times, even though nothing really changes in 
the view...

Biggest culprits seems to be: Moving Ranges :)

The on-the-fly spellchecker code e.g. is using moving ranges. The moving 
ranges can trigger view updates via notifyAboutRangeChange which gets called 
in quite a few places, e.g.:

#0  0x00007f5553560458 in KTextEditor::ViewPrivate::delayedUpdateOfView()@plt 
() from /home/milian/projects/compiled/kf5-dbg/lib64/libKF5TextEditor.so.5
#1  0x00007f5553563246 in Kate::TextBuffer::notifyAboutRangeChange 
(this=<optimized out>, view=0x0, startLine=0, endLine=0, 
rangeWithAttribute=false)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/buffer/
katetextbuffer.cpp:991
#2  0x00007f55536917f2 in KateOnTheFlyChecker::misspelling 
(this=0x55a29c4922d0, word=..., start=<optimized out>)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/spellcheck/
ontheflycheck.cpp:609

Or also the following. Note there's a frame for TextRange::setFeedback missing 
below somehow (devirtualization?!):

#0  0x00007f9aaddf3458 in KTextEditor::ViewPrivate::delayedUpdateOfView()@plt 
() from /home/milian/projects/compiled/kf5-dbg/lib64/libKF5TextEditor.so.5
#1  0x00007f9aaddf6246 in Kate::TextBuffer::notifyAboutRangeChange 
(this=<optimized out>, view=0x0, startLine=0, endLine=0, 
rangeWithAttribute=false)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/buffer/
katetextbuffer.cpp:991
#2  0x00007f9aadf234a6 in KateOnTheFlyChecker::deleteMovingRangeQuickly 
(this=this at entry=0x55e2bd1f9390, range=range at entry=0x55e2bddac920)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/spellcheck/
ontheflycheck.cpp:863
#3  0x00007f9aadf2361c in KateOnTheFlyChecker::spellCheckDone 
(this=0x55e2bd1f9390) at /home/milian/projects/kf5/src/frameworks/ktexteditor/
src/spellcheck/ontheflycheck.cpp:633

This will then eventually trigger a relayout:

#0  0x00007f554ea21f28 in QTextLine::layout_helper(int) () from /usr/lib/
libQt5Gui.so.5
#1  0x00007f554ea231a1 in QTextLine::setLineWidth(double) () from /usr/lib/
libQt5Gui.so.5
#2  0x00007f555361bd28 in KateRenderer::layoutLine (this=0x55a29c4cc9e0, 
lineLayout=..., maxwidth=1810, cacheLayout=<optimized out>)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/render/
katerenderer.cpp:1033
#3  0x00007f55536217e6 in KateLayoutCache::line 
(this=this at entry=0x55a29ca0e2c0, realLine=realLine at entry=0, 
virtualLine=virtualLine at entry=-1)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/render/
katelayoutcache.cpp:313
#4  0x00007f5553621f58 in KateLayoutCache::updateViewCache 
(this=this at entry=0x55a29ca0e2c0, startPos=..., newViewLineCount=48, 
newViewLineCount at entry=-1, 
    viewLinesScrolled=viewLinesScrolled at entry=0) at /home/milian/projects/kf5/
src/frameworks/ktexteditor/src/render/katelayoutcache.cpp:242
#5  0x00007f555366caa0 in KateViewInternal::tagLines (this=0x55a29c3ead80, 
start=..., end=..., realCursors=realCursors at entry=true)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/view/
kateviewinternal.cpp:2203
#6  0x00007f555366cd49 in KateViewInternal::tagLines (this=<optimized out>, 
start=<optimized out>, end=<optimized out>, realLines=realLines at entry=true)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/view/
kateviewinternal.cpp:2176
#7  0x00007f55536548ff in KTextEditor::ViewPrivate::tagLines 
(this=this at entry=0x55a29ca46050, start=<optimized out>, end=<optimized out>, 
realLines=realLines at entry=true)
    at /home/milian/projects/kf5/src/frameworks/ktexteditor/src/view/
kateview.cpp:2012
#8  0x00007f5553663735 in KTextEditor::ViewPrivate::slotDelayedUpdateOfView 
(this=0x55a29ca46050) at /home/milian/projects/kf5/src/frameworks/ktexteditor/
src/view/kateview.cpp:3385

I don't see an easy way around this. I just note that some calls to 
`m_buffer.notifyAboutRangeChange` in katetextrange.cpp are guarded with 

if (m_attribute || m_feedback)

while others are not, e.g. in TextRange::setFeedback. Adding those checks 
could potentially remove some relayouting calls, but I'm not sure whether this 
is OK to do or not. Christoph?

I'll dig a bit deeper and see if more can be found and removed...

-- 
Milian Wolff
mail at milianw.de
http://milianw.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.kde.org/pipermail/kwrite-devel/attachments/20180323/1e7cf336/attachment.sig>


More information about the KWrite-Devel mailing list