Optimize wrapping long lines in wxRichTextCtrl
When one inserts one big line to a wxRichTextCtrl that is too long (say 300k words of average size 9), then wxRichTextCtrl could freeze for a few seconds. It could also freeze again when the control is resized (such that word wrapping is triggered again). Problem: `wxRichTextParagraph::AllocateLine(int pos)` can be called many times. Each call triggers `m_cachedLines.Item(pos)`, which traverses the linked list. As a result we get quadratic time complexity. In this commit, we improve the function by also caching the lines in a vector, which supports random access in O(1) time.
This commit is contained in:
@@ -4654,6 +4654,7 @@ protected:
|
|||||||
|
|
||||||
// The lines that make up the wrapped paragraph
|
// The lines that make up the wrapped paragraph
|
||||||
wxRichTextLineList m_cachedLines;
|
wxRichTextLineList m_cachedLines;
|
||||||
|
wxVector<wxRichTextLine*> m_cachedLinesVect;
|
||||||
|
|
||||||
// Whether the paragraph is impacted by floating objects from above
|
// Whether the paragraph is impacted by floating objects from above
|
||||||
int m_impactedByFloatingObjects;
|
int m_impactedByFloatingObjects;
|
||||||
|
@@ -5697,6 +5697,7 @@ void wxRichTextParagraph::Copy(const wxRichTextParagraph& obj)
|
|||||||
void wxRichTextParagraph::ClearLines()
|
void wxRichTextParagraph::ClearLines()
|
||||||
{
|
{
|
||||||
WX_CLEAR_LIST(wxRichTextLineList, m_cachedLines);
|
WX_CLEAR_LIST(wxRichTextLineList, m_cachedLines);
|
||||||
|
m_cachedLinesVect.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get/set the object size for the given range. Returns false if the range
|
/// Get/set the object size for the given range. Returns false if the range
|
||||||
@@ -6529,7 +6530,8 @@ wxRichTextLine* wxRichTextParagraph::AllocateLine(int pos)
|
|||||||
{
|
{
|
||||||
if (pos < (int) m_cachedLines.GetCount())
|
if (pos < (int) m_cachedLines.GetCount())
|
||||||
{
|
{
|
||||||
wxRichTextLine* line = m_cachedLines.Item(pos)->GetData();
|
assert(m_cachedLinesVect.size() == m_cachedLines.GetCount());
|
||||||
|
wxRichTextLine* line = m_cachedLinesVect[pos];
|
||||||
line->Init(this);
|
line->Init(this);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
@@ -6537,6 +6539,7 @@ wxRichTextLine* wxRichTextParagraph::AllocateLine(int pos)
|
|||||||
{
|
{
|
||||||
wxRichTextLine* line = new wxRichTextLine(this);
|
wxRichTextLine* line = new wxRichTextLine(this);
|
||||||
m_cachedLines.Append(line);
|
m_cachedLines.Append(line);
|
||||||
|
m_cachedLinesVect.push_back(line);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6555,6 +6558,7 @@ bool wxRichTextParagraph::ClearUnusedLines(int lineCount)
|
|||||||
delete line;
|
delete line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_cachedLinesVect.resize(lineCount);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user