PDA

View Full Version : QTextEdit Performance handling large paragraphs



netuno
10th August 2008, 00:34
Hi folks,

I'm using QTextEdit (qt4 btw) on my application, and I've just hit a wall so to speak. The thing is that my application needs to handle large paragraphs (something like a paragraph of 17 pages long), and QTextEdit really doesn't handle that well. If I break the same text into multiple paragraphs, performance is just fine, but on a single one, it's just awful.
I've read on some Qt3 that QTextEdit only performed the layout only on the text visible on the screen. It doesn't seem to do that anymore, otherwise performance would be fine, right?
So any ideas on how I should proceed on getting QTextEdit (and it's internal classes) to perform well on this matter? Would I have to redo the painting of QTextEdit via subclass? Any other way?
I appreciate any help on this matter.

Thanks

Luiz

thomaspu
10th August 2008, 02:51
I seem to remember encountering the same issue when I was doing performance tuning on a console application that I wrote. I wrote a special app that just had a QTextEdit and was trying to see what was slow/fast. Large paragraphs really slowed it down, couldn't find a way around it with how they wrote QTextEdit. I ended up just creating my own display widget instead of using QTextEdit.

Paul

caduel
10th August 2008, 08:54
perhaps QPlainTextEdit is enough for your needs?

netuno
10th August 2008, 15:08
I ended up just creating my own display widget instead of using QTextEdit.

Paul

What did you have to rewrite in order to get a good performance with large paragraphs? Did you just subclassed QTextEdit and did you painting?


perhaps QPlainTextEdit is enough for your needs?

It isn't, I need to handle Rich Text on my app. Anyways QPlainTextEdit suffers from the same problem. It just takes a slightly larger paragraph for the slow down to happen.

thomaspu
11th August 2008, 17:29
You'll likely need to do a little more work than I did to get decent performance depending on how much of QTextEdit's functionallity you want to keep around. I didn't dig deeply into QTextEdit source, but based upon seeing how it probably worked on paragraphs at a time, I decided it was better to make my own QTextEdit-like widget. During this time I was putting large paragraphs of HTML for QTextEdit to mess with. Small paragraphs worked just fine.

In my console app, the problem that I had was that I was often sending large paragraphs of HTML to the QTextEdit and it was taking waaaay too long for it to process them and paint the widget.

The end result of my efforts was to get rid of HTML stuff (less overhead) and do my own painting. You might not need to do your own painting, I did it largely because QTextEdit was just way too slow for the performance level I was gearing for.

I basically just made a widget that inherited from QWidget so that I could do my own painting based upon only the data I wanted it to work with, unlike working with an entire paragraph. The end result for me was much faster. Just a side note, the painting speed in Qt 4.4.0 is much improved from earlier 4.x versions.

Hope that helps,
Paul

netuno
11th August 2008, 21:41
The problem doesn't seen to be in the painting, but on the editing. I reimplented the paintEvent of QTextEdit on a subclass to test it. Even without painting anything performance is bad.

It seems that when I edit a large paragraph, Qt updates the layout of the entire paragraph, and not just what's on screen. Which with long paragraphs means bad performance. I think I need to reimplement the layout class (QAbstractTextDocumentLayout) to make it smarter on this matter.

Right now I'm studying the Scribe classes (QTextEdit, QTextDocument, QTextLayout, etc) to get a better idea of what I have to do to fix this behavior.

I'm already using Qt 4.4.1 btw.

Any other ideas on this matter? It seems I'm in deep trouble...

EDIT: Trolltech on this matter: http://trolltech.com/developer/task-tracker/index_html?method=entry&id=135240 A high priority bug almost 2 years old :mad:. Geez Qt wasn't cheap for something like this to happen.

thomaspu
11th August 2008, 21:58
I recognize that bug report! Saw that back when I was trying to make things faster. I didn't mean to put a whole lot of emphasis on the painting being the problem, although my last post sure did make it sound that way. I essentially hit two performance hurdles:
1) QTextEdit & slow paragraphs
2) QTextEdit with HTML or rich text being too slow to paint for my tastes

My solution was a brand new class from scratch. I didn't need most of the QTextEdit functionallity/overhead. Sounds like you are headed in the right direction. If you have a full-blown version of VS 2008 at your fingertips, do a performance tuning session and see where at in the bowels of QTextEdit you're spending the most of your processing time.

Good luck,
Paul

bunjee
12th August 2008, 23:28
Thomaspu,

maybe you could post your home-Made fast QTextEdit widget, I'm interested.

thomaspu
13th August 2008, 00:11
Unfortunately its not geared towards the same functionality as a QTextEdit and lacks nearly all of the functions that QTextEdit provides (I didn't put in what I didn't need). I would classify it more as a specially designed display widget for XTerm emulation than a text editor widget.

Paul

HeikoK
2nd February 2009, 14:25
I am currently writing a custom widget on the basis of QWidget that is optimized for speed and large text files/streams. It can be used as a fast log viewer or programming text editor. It is very fast and supports foreground/background colors, bolding, underlining and italics. It has an optional split screen (lower part keeps tailing the stream, while the upper part of the split screen can be scrolled by the user. Split screen comes up if the user scroll up in the history. Split screen can be resized.) and optional line wrapping and indentation of wrapped lines.

Performance is very good.

fullmetalcoder
3rd February 2009, 19:24
In case you do not need full rich text support but only but only character formatting you could consider using QCodeEdit (http://qcodeedit.edyuk.org). It offers pretty good performances and decent formatting. Most of the formatting limitations, intentional to maximize performance for the "code editing" use case could reasonnably easily be removed and you wouldn't have to start from scratch. If however you need more complex formatting (e.g tables, images, paragraph/line distinction, ...) your better options are : reimplement as much of the layout process as QTextEdit allows you to (presumably using QAbstractTextDocumentLayout) (it probably won't be easy as QTextEdit default layout is part of the "private" Qt headers) or have a look at other Qt-based editors (like KWord) that may have found a "solution" to this problem.

skimber
5th February 2009, 22:16
I'm having the same problem also. It looks like it is entirely the painting slowing everything down. (We haven't got to the editing anything yet) Currently we read 700k+ lines into a stream, then write the stream to a QString. These are very fast, it's the output that's killing us. Writing to either setText or setPlainText blocks severely. We are just now trying to add a timer to control the output to the screen with some early success. It takes 4 times longer but at least it's not blocking. Still it's a pretty big problem for us.

HeikoK
7th February 2009, 13:55
I have had the same performance problems and solved them by looking at the problem from a completely different perspective.
A human eye is only capable of viewing a certain amount of frames per second. Thus, when displaying fast data streams you don't have to render the screen after each new line as the human eye could not see it.
What you want to do is seperate the original problem into two entirely unrelated problems, i. e. the buffer and the viewer problems.

I needed a very fast text stream control with character format support such as foreground and background colors, bolding, underlining and italics for an open source MUD client project. QTextEdit was *way* too slow. QPlainTextEdit is a bit faster, but still way too slow. The problem is the underlying QTextDocument and its complex rendering. The drawing performance itself is not the problem. I use two synchronized buffers. A std::deque<std::deque<TChar*> > structure for the character format (TChar) and a synchronized QStringList for the text itself. This has the advantage that you can do fast string lookups and replacements without the need to adapt the corresponding format buffer if there is a need to do so.

The display itself renders snapshots of the part of the buffer that is of interest. In a streaming scenario this is usually the end of the buffer unless the user scrolls up in the buffer in which case the display control renders the part of the text buffer that is visible on the screen at that particular time. This way the user has real time access to any part of the text buffer that he is interested in.

The text rendering itself can be optimized greatly, by only rendering the text of the new lines that have not been rendered yet and scrolling up old lines in the graphics buffe as rendering text is inherently complex and slow.

If some part in the buffer changes and that particular part of the screen is currently displayed, then you only want to update the rectangles of the affected characters and not the entire screen.

Anyways, the speed is outstanding now.

You can have a look at the code here:
http://github.com/HeikoKoehn/mudlet/tree/master

gpwunder
6th July 2010, 19:04
It appears that the link : "http://github.com/HeikoKoehn/mudlet/tree/master" is down.
Do you have a new one?

HeikoK
1st September 2010, 22:58
main site: http://www.mudlet.org
source code available here: http://mudlet.git.sourceforge.net