WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED CONFIGURATION CHANGED
52380
Lazily generate and store logical ordering of InlineBoxes
https://bugs.webkit.org/show_bug.cgi?id=52380
Summary
Lazily generate and store logical ordering of InlineBoxes
Levi Weintraub
Reported
2011-01-13 11:00:15 PST
Created
attachment 78828
[details]
Proposed patch Currently, iterating across InlineBoxes logically involves an n^2 algorithm and the result isn't stored. For RTL and BiDi content, this can represent a lot of wasted work, particularly as new places pop up that need access to this info (see
https://bugs.webkit.org/show_bug.cgi?id=38087
). I propose lazily generating this ordering and storing it so future lookups and iteration are O(1). I've also moved the algorithm to RootInlineBox so it hopefully will be updated with Rendering changes.
Attachments
Proposed patch
(7.88 KB, patch)
2011-01-13 11:00 PST
,
Levi Weintraub
no flags
Details
Formatted Diff
Diff
Proposed Patch
(7.90 KB, patch)
2011-01-13 11:37 PST
,
Levi Weintraub
no flags
Details
Formatted Diff
Diff
Patch
(9.47 KB, patch)
2011-01-14 14:50 PST
,
Levi Weintraub
eric
: review-
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Ryosuke Niwa
Comment 1
2011-01-13 11:35:02 PST
This is very exciting patch! I talked with Levi in person, and we realized that it has many use cases because it allows us to binary search an inline box. This may allow us to resolve
https://bugs.webkit.org/show_bug.cgi?id=25298
easily.
Levi Weintraub
Comment 2
2011-01-13 11:37:34 PST
Created
attachment 78836
[details]
Proposed Patch Fixing a comment. This could be used, for example, to speed up getInlineBoxAndOffset to Log(N) time from its current O(N) by looking at the start/end position of inline boxes compared to the offset.
Eric Seidel (no email)
Comment 3
2011-01-13 14:10:23 PST
Comment on
attachment 78836
[details]
Proposed Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=78836&action=review
I suspect this is not invalidating when necessary.
> Source/WebCore/editing/visible_units.cpp:1039 > + const Vector<InlineBox*> leafBoxesInLogicalOrder = rootBox->leafBoxesInLogicalOrder();
I don't think you want the const here. seems meaningless.
> Source/WebCore/rendering/RootInlineBox.cpp:219 > + m_leafBoxesInLogicalOrder.clear();
Don't we need to invalidate thsi when adding children too?
> Source/WebCore/rendering/RootInlineBox.cpp:566 > +void RootInlineBox::determineLogicalOrderOfLeafBoxes() const
I assume this is just copied from the previous location and otherwise not modified (except to store in a vector)?
Levi Weintraub
Comment 4
2011-01-13 14:42:05 PST
Thanks for taking a look at this! (In reply to
comment #3
)
> (From update of
attachment 78836
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=78836&action=review
> > I suspect this is not invalidating when necessary. > > > Source/WebCore/editing/visible_units.cpp:1039 > > + const Vector<InlineBox*> leafBoxesInLogicalOrder = rootBox->leafBoxesInLogicalOrder(); > > I don't think you want the const here. seems meaningless. > > > Source/WebCore/rendering/RootInlineBox.cpp:219 > > + m_leafBoxesInLogicalOrder.clear(); > > Don't we need to invalidate thsi when adding children too?
For sure. Currently we only ever add line boxes on line creation so we wouldn't get into this case, but not doing this would be leaving us open for future problems.
> > Source/WebCore/rendering/RootInlineBox.cpp:566 > > +void RootInlineBox::determineLogicalOrderOfLeafBoxes() const > > I assume this is just copied from the previous location and otherwise not modified (except to store in a vector)?
Correct. The relevance of this patch is that it speeds up access to logical InlineBox ordering, which is information we iterate through in several places. Caching it and using this source should allow us to speed up and simplify these code paths.
Eric Seidel (no email)
Comment 5
2011-01-13 15:00:49 PST
Yeah, I'm a big fan of the patch. Just need to be cautious when adding caches like this that we don't end up with them invalid (and thus causing security bugs). :)
Levi Weintraub
Comment 6
2011-01-14 14:50:14 PST
Created
attachment 79005
[details]
Patch
Eric Seidel (no email)
Comment 7
2011-01-14 14:54:04 PST
Comment on
attachment 79005
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=79005&action=review
Looks good. tis OK as is, but we could go another round now, or we can clean up more of this (old ugly!) code in later patches.
> Source/WebCore/rendering/RootInlineBox.cpp:209 > +void RootInlineBox::childAdded()
Seems if we're adding this method we might as well pass the InlineBox*, even if it's ignored.
> Source/WebCore/rendering/RootInlineBox.cpp:587 > + if (r->bidiLevel() > maxLevel) > + maxLevel = r->bidiLevel(); > + if (r->bidiLevel() < minLevel) > + minLevel = r->bidiLevel();
Hah. These are just std::min, std::max :)
> Source/WebCore/rendering/RootInlineBox.cpp:615 > + while (iter != end) { > + if ((*iter)->bidiLevel() >= minLevel) > + break; > + ++iter; > + }
This is repeated twice and should be an inline which returns a bool or similar maybe?
> Source/WebCore/rendering/RootInlineBox.h:79 > void childRemoved(InlineBox* box);
"box" can be removed.
Levi Weintraub
Comment 8
2011-01-14 14:58:06 PST
(In reply to
comment #7
)
> (From update of
attachment 79005
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=79005&action=review
> > Looks good. tis OK as is, but we could go another round now, or we can clean up more of this (old ugly!) code in later patches. > > > Source/WebCore/rendering/RootInlineBox.cpp:209 > > +void RootInlineBox::childAdded() > > Seems if we're adding this method we might as well pass the InlineBox*, even if it's ignored. > > > Source/WebCore/rendering/RootInlineBox.cpp:587 > > + if (r->bidiLevel() > maxLevel) > > + maxLevel = r->bidiLevel(); > > + if (r->bidiLevel() < minLevel) > > + minLevel = r->bidiLevel(); > > Hah. These are just std::min, std::max :) > > > Source/WebCore/rendering/RootInlineBox.cpp:615 > > + while (iter != end) { > > + if ((*iter)->bidiLevel() >= minLevel) > > + break; > > + ++iter; > > + } > > This is repeated twice and should be an inline which returns a bool or similar maybe? > > > Source/WebCore/rendering/RootInlineBox.h:79 > > void childRemoved(InlineBox* box); > > "box" can be removed.
All great points, thanks for the review!
mitz
Comment 9
2011-01-14 15:56:27 PST
What’s the memory use impact of adding 8 bytes to every root box in every page? What’s the running time impact of this change? Is this a good time/space trade-off?
Ryosuke Niwa
Comment 10
2011-01-14 16:03:23 PST
(In reply to
comment #9
)
> What’s the memory use impact of adding 8 bytes to every root box in every page? What’s the running time impact of this change? Is this a good time/space trade-off?
In the case of selection / cursor movement, we're not modifying the DOM so being able to avoid running O(n^2) algorithm every time user changes selection will likely improve the performance quite significantly. We can also use profiler to see how much time/space trade-off we have.
Eric Seidel (no email)
Comment 11
2011-01-14 16:05:35 PST
Comment on
attachment 79005
[details]
Patch Wow, I feel like noob. There are a lot of lineboxes on the page. I suspect this cache is very expensive.
mitz
Comment 12
2011-01-14 16:45:47 PST
(In reply to
comment #10
)
> (In reply to
comment #9
) > being able to avoid running O(n^2) algorithm every time user changes selection will likely improve the performance quite significantly.
What are typical values of n for this sort of operation? Are there bugs in bugs.webkit.org or other publically-accessible bug databases showing bad responsiveness of selection operations that have been tracked down to this computation? You might want to consider replacing m_floats with an m_rareData that encompasses a vector for floats and this new cache.
Antti Koivisto
Comment 13
2011-01-15 09:20:21 PST
If these caches are actually used the memory will balloon far beyond the already bad pointer-per-root-inline-box. All those pointer vectors (in this patch each cache is at least 128 bytes even if it has just one item, though that could be optimized) will add up. On the other hand if the caches are not used then all those null pointers are wasted space. A better approach would be to have a non-member cache. Search for "RareData" in WebCore to find a number of examples. You would still need to take care that it won't bloat too much even if someone touches all nodes in a huge document. First thing to do however is to make sure you are fixing a real problem. You should do profiling before writing performance patches.
Ahmad Saleem
Comment 14
2024-06-22 03:11:47 PDT
@Alan - is this needed anymore?
zalan
Comment 15
2024-06-22 05:32:47 PDT
(In reply to Ahmad Saleem from
comment #14
)
> @Alan - is this needed anymore?
nope. Thank you.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug