Introduces a few ad-hoc modifications to the DAFSA aimed to increase
performance while keeping the data size small.
- The 'first layer' of nodes is extracted out and replaced with a lookup
table. This turns the search for the first character from O(n) to O
(1), and doesn't increase the data size because all first characters
in the set of named character references have the
values 'a'-'z'/'A'-'Z', so a lookup array of exactly 52 elements can
be used. The lookup table stores the cumulative "number" fields that
would be calculated by a linear scan that matches a given node, thus
allowing the unique index to be built-up as normal with a O(1) search
instead of a linear scan.
- The 'second layer' of nodes is also extracted out and searches of the
second layer are done using a bit field of 52 bits (the set bits of
the bit field depend on the first character's value), where each set
bit corresponds to one of 'a'-'z'/'A'-'Z' (similar to the first
layer, the second layer can only contain ASCII alphabetic
characters). The bit field is then re-used (along with an offset) to
get the index into the array of second layer nodes. This technique
ultimately allows for storing the minimum number of nodes in the
second layer, and therefore only increasing the size of the data by
the size of the 'first to second layer link' info which is 52 * 8 =
416 bytes.
- After the second layer, the rest of the data is stored using a
mostly-normal DAFSA, but there are still a few differences:
- The "number" field is cumulative, in the same way that the
first/second layer store a cumulative "number" field. This cuts
down slightly on the amount of work done during the search of a
list of children, and we can get away with it because the
cumulative "number" fields of the remaining nodes in the DAFSA
(after the first and second layer nodes were extracted out) happens
to require few enough bits that we can store the cumulative version
while staying under our 32-bit budget.
- Instead of storing a 'last sibling' flag to denote the end of a
list of children, the length of each node's list of children is
stored. Again, this is mostly done just because there are enough
bits available to do so while keeping the DAFSA node within 32
bits.
- Note: Together, these modifications open up the possibility of
using a binary search instead of a linear search over the
children, but due to the consistently small lengths of the lists
of children in the remaining DAFSA, a linear search actually seems
to be the better option.
The new data size is 24,724 bytes, up from 24,412 bytes (+312, -104 from
the 52 first layer nodes going from 4-bytes to 2-bytes, and +416 from
the addition of the 'first to second layer link' data).
In terms of raw matching speed (outside the context of the tokenizer),
this provides about a 1.72x speedup.
In very named-character-reference-heavy tokenizer benchmarks, this
provides about a 1.05x speedup (the effect of named character reference
matching speed is diluted when benchmarking the tokenizer).
Additionally, fixes the size of the named character reference data when
targeting Windows.
|
||
|---|---|---|
| .devcontainer | ||
| .github | ||
| AK | ||
| Base/res | ||
| Documentation | ||
| Libraries | ||
| Meta | ||
| Services | ||
| Tests | ||
| Toolchain | ||
| UI | ||
| Utilities | ||
| .clang-format | ||
| .clang-tidy | ||
| .clangd | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .gn | ||
| .mailmap | ||
| .pre-commit-config.yaml | ||
| .prettierignore | ||
| .prettierrc | ||
| .swift-format | ||
| .swift-version | ||
| .ycm_extra_conf.py | ||
| CMakeLists.txt | ||
| CMakePresets.json | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| ISSUES.md | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| SECURITY.md | ||
| vcpkg-configuration.json | ||
| vcpkg.json | ||
Ladybird
Ladybird is a truly independent web browser, using a novel engine based on web standards.
Important
Ladybird is in a pre-alpha state, and only suitable for use by developers
Features
We aim to build a complete, usable browser for the modern web.
Ladybird uses a multi-process architecture with a main UI process, several WebContent renderer processes, an ImageDecoder process, and a RequestServer process.
Image decoding and network connections are done out of process to be more robust against malicious content. Each tab has its own renderer process, which is sandboxed from the rest of the system.
At the moment, many core library support components are inherited from SerenityOS:
- LibWeb: Web rendering engine
- LibJS: JavaScript engine
- LibWasm: WebAssembly implementation
- LibCrypto/LibTLS: Cryptography primitives and Transport Layer Security
- LibHTTP: HTTP/1.1 client
- LibGfx: 2D Graphics Library, Image Decoding and Rendering
- LibUnicode: Unicode and locale support
- LibMedia: Audio and video playback
- LibCore: Event loop, OS abstraction layer
- LibIPC: Inter-process communication
How do I build and run this?
See build instructions for information on how to build Ladybird.
Ladybird runs on Linux, macOS, Windows (with WSL2), and many other *Nixes.
How do I read the documentation?
Code-related documentation can be found in the documentation folder.
Get in touch and participate!
Join our Discord server to participate in development discussion.
Please read Getting started contributing if you plan to contribute to Ladybird for the first time.
Before opening an issue, please see the issue policy and the detailed issue-reporting guidelines.
The full contribution guidelines can be found in CONTRIBUTING.md.
License
Ladybird is licensed under a 2-clause BSD license.