Aho-Corasick attribute selector pruning.

If a stylesheet has a lot of different rules bucketed on the same
attribute (some extensions inject user stylesheets that do this,
for one), we can do better than testing each and every one of them
individually. As an optimization, we can use SubstringSetMatcher
(an implementation of the Aho-Corasick string matching algorithm)
to rapidly test against all of them in linear time in the length of
the attribute value. This takes a bit of RAM for such stylesheets
(e.g. a 743-element tree from the Extension subtest takes ~153 kB),
but speeds up their matching significantly.

Style microbenchmarks (Zen 2, LTO but no PGO; only Extension,
News, Sports and Video actually get behavioral differences):

Parse (µs)             Before     After    Perf      95% CI (BCa)
=================== ========= ========= ======= =================
ECommerce                1693      1717   -1.4%  [ -1.5%,  -1.2%]
Encyclopedia             9170      9179   -0.1%  [ -0.2%,  -0.0%]
Extension                1637      1662   -1.5%  [ -1.6%,  -1.3%]
News                    10267     10288   -0.2%  [ -0.3%,  -0.1%]
Search                   6236      6260   -0.4%  [ -0.4%,  -0.3%]
Social1                 21045     21046   -0.0%  [ -0.1%,  +0.1%]
Social2                   722       737   -2.0%  [ -2.2%,  -1.9%]
Sports                  73974     74119   -0.2%  [ -0.3%,  -0.1%]
Video                   38936     39101   -0.4%  [ -0.5%,  -0.4%]
Geometric mean                            -0.7%  [ -0.8%,  -0.6%]

Initial style (µs)     Before     After    Perf      95% CI (BCa)
=================== ========= ========= ======= =================
ECommerce               11477     11419   +0.5%  [ +0.4%,  +0.6%]
Encyclopedia           110338    110068   +0.2%  [ +0.2%,  +0.3%]
Extension              261834    137113  +91.0%  [+90.8%, +91.1%]
News                    43919     43823   +0.2%  [ +0.1%,  +0.3%]
Search                   2775      2800   -0.9%  [ -1.0%,  -0.8%]
Social1                 26140     26114   +0.1%  [ +0.0%,  +0.2%]
Social2                  1087      1061   +2.4%  [ +2.2%,  +2.6%]
Sports                  37874     36289   +4.4%  [ +4.3%,  +4.4%]
Video                   41291     41292   -0.0%  [ -0.1%,  +0.1%]
Geometric mean                            +8.3%  [ +8.2%,  +8.3%]

Recalc style (µs)      Before     After    Perf      95% CI (BCa)
=================== ========= ========= ======= =================
ECommerce               14568     14544   +0.2%  [ +0.0%,  +0.3%]
Encyclopedia            98240     97627   +0.6%  [ +0.5%,  +0.8%]
Extension              257682    130824  +97.0%  [+96.8%, +97.2%]
News                    33016     33000   +0.0%  [ -0.1%,  +0.2%]
Search                    251       249   +0.6%  [ +0.4%,  +0.8%]
Social1                 17993     17884   +0.6%  [ +0.5%,  +0.7%]
Social2                   602       580   +3.8%  [ +3.4%,  +4.0%]
Sports                  29106     27465   +6.0%  [ +5.9%,  +6.1%]
Video                   29407     29343   +0.2%  [ +0.1%,  +0.5%]
Geometric mean                            +9.2%  [ +9.1%,  +9.3%]

Change-Id: I5fe9d74fae11c30e7dc5c2cd62f2944e2cba50eb
Bug: 1318773
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3581992
Reviewed-by: Philip Rogers <pdr@chromium.org>
Commit-Queue: Steinar H Gunderson <sesse@chromium.org>
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1002855}
9 files changed
tree: 238f6c3e54af250bb8ae957e109e0ab058267886
  1. android_webview/
  2. apps/
  3. ash/
  4. base/
  5. build/
  6. build_overrides/
  7. buildtools/
  8. cc/
  9. chrome/
  10. chromecast/
  11. chromeos/
  12. codelabs/
  13. components/
  14. content/
  15. courgette/
  16. crypto/
  17. dbus/
  18. device/
  19. docs/
  20. extensions/
  21. fuchsia/
  22. fuchsia_webengine/
  23. gin/
  24. google_apis/
  25. google_update/
  26. gpu/
  27. headless/
  28. infra/
  29. ios/
  30. ipc/
  31. media/
  32. mojo/
  33. native_client_sdk/
  34. net/
  35. pdf/
  36. ppapi/
  37. printing/
  38. remoting/
  39. rlz/
  40. sandbox/
  41. services/
  42. skia/
  43. sql/
  44. storage/
  45. styleguide/
  46. testing/
  47. third_party/
  48. tools/
  49. ui/
  50. url/
  51. weblayer/
  52. .clang-format
  53. .clang-tidy
  54. .eslintrc.js
  55. .git-blame-ignore-revs
  56. .gitattributes
  57. .gitignore
  58. .gn
  59. .mailmap
  60. .rustfmt.toml
  61. .vpython
  62. .vpython3
  63. .yapfignore
  64. AUTHORS
  65. BUILD.gn
  66. CODE_OF_CONDUCT.md
  67. codereview.settings
  68. DEPS
  69. DIR_METADATA
  70. ENG_REVIEW_OWNERS
  71. LICENSE
  72. LICENSE.chromium_os
  73. OWNERS
  74. PRESUBMIT.py
  75. PRESUBMIT_test.py
  76. PRESUBMIT_test_mocks.py
  77. README.md
  78. WATCHLISTS
README.md

Logo Chromium

Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all users to experience the web.

The project's web site is https://www.chromium.org.

To check out the source code locally, don't use git clone! Instead, follow the instructions on how to get the code.

Documentation in the source is rooted in docs/README.md.

Learn how to Get Around the Chromium Source Code Directory Structure .

For historical reasons, there are some small top level directories. Now the guidance is that new top level directories are for product (e.g. Chrome, Android WebView, Ash). Even if these products have multiple executables, the code should be in subdirectories of the product.

If you found a bug, please file it at https://crbug.com/new.