Changeset 260762 in webkit


Ignore:
Timestamp:
Apr 27, 2020 9:47:24 AM (4 years ago)
Author:
Darin Adler
Message:

Improve performance of commonInclusiveAncestor for deeply nested nodes
https://bugs.webkit.org/show_bug.cgi?id=211078

Reviewed by Antti Koivisto.

  • dom/Node.cpp:

(WebCore::depth): Added.
(WebCore::commonInclusiveAncestor): Replaced implementation that walks the
parent chain of the second node repeatedly with one that walks the parent
chain of each node twice.

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r260759 r260762  
     12020-04-27  Darin Adler  <darin@apple.com>
     2
     3        Improve performance of commonInclusiveAncestor for deeply nested nodes
     4        https://bugs.webkit.org/show_bug.cgi?id=211078
     5
     6        Reviewed by Antti Koivisto.
     7
     8        * dom/Node.cpp:
     9        (WebCore::depth): Added.
     10        (WebCore::commonInclusiveAncestor): Replaced implementation that walks the
     11        parent chain of the second node repeatedly with one that walks the parent
     12        chain of each node twice.
     13
    1142020-04-27  Daniel Bates  <dabates@apple.com>
    215
  • trunk/Source/WebCore/dom/Node.cpp

    r260753 r260762  
    26132613}
    26142614
     2615static size_t depth(Node& node)
     2616{
     2617    size_t depth = 0;
     2618    auto ancestor = &node;
     2619    while ((ancestor = ancestor->parentNode()))
     2620        ++depth;
     2621    return depth;
     2622}
     2623
    26152624RefPtr<Node> commonInclusiveAncestor(Node& a, Node& b)
    26162625{
    2617     for (auto ancestorA = &a; ancestorA; ancestorA = ancestorA->parentNode()) {
    2618         for (auto ancestorB = &b; ancestorB; ancestorB = ancestorB->parentNode()) {
    2619             if (ancestorA == ancestorB)
    2620                 return ancestorA;
    2621         }
    2622     }
    2623     return nullptr;
     2626    // This first check isn't needed for correctness, but it is cheap and likely to be
     2627    // common enough to be worth optimizing so we don't have to walk to the root.
     2628    if (&a == &b)
     2629        return &a;
     2630    auto [depthA, depthB] = std::make_tuple(depth(a), depth(b));
     2631    auto [x, y, difference] = depthA > depthB
     2632        ? std::make_tuple(&a, &b, depthA - depthB)
     2633        : std::make_tuple(&b, &a, depthB - depthA);
     2634    for (decltype(difference) i = 0; i < difference; ++i)
     2635        x = x->parentNode();
     2636    while (x != y) {
     2637        x = x->parentNode();
     2638        y = y->parentNode();
     2639    }
     2640    return x;
    26242641}
    26252642
Note: See TracChangeset for help on using the changeset viewer.