rusteerio 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/README.md +20 -20
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/native/src/lib.rs +2 -0
- package/native/src/runtime.rs +23 -0
- package/package.json +1 -1
- package/rusteerio.darwin-arm64.node +0 -0
- package/rusteerio.darwin-x64.node +0 -0
- package/rusteerio.linux-arm64-gnu.node +0 -0
- package/rusteerio.linux-arm64-musl.node +0 -0
- package/rusteerio.linux-x64-gnu.node +0 -0
- package/rusteerio.linux-x64-musl.node +0 -0
- package/rusteerio.win32-arm64-msvc.node +0 -0
- package/rusteerio.win32-x64-msvc.node +0 -0
package/Cargo.lock
CHANGED
package/Cargo.toml
CHANGED
package/README.md
CHANGED
|
@@ -198,18 +198,18 @@ Rusteerio was faster in **all 45 cases**. Representative results:
|
|
|
198
198
|
|
|
199
199
|
| Workload | CPUs | Cheerio | rusteerio | rusteerio |
|
|
200
200
|
| --- | ---: | ---: | ---: | --- |
|
|
201
|
-
| Load/query, 500 articles | 1 |
|
|
202
|
-
| Load/query, 5,000 articles | 1 |
|
|
203
|
-
| HTML mutations, 5,000 articles | 1 |
|
|
204
|
-
| XML load/query, 5,000 articles | 1 |
|
|
205
|
-
| Extract 16 documents × 5,000 articles | 1 |
|
|
206
|
-
| Extract 16 documents × 5,000 articles | 8 |
|
|
207
|
-
| Nested callback extraction, 8 × 500 articles | 8 |
|
|
208
|
-
| Cold extraction, 16 × 20 articles | 8 |
|
|
209
|
-
| 8 concurrent batches × 8 × 300 articles | 8 |
|
|
210
|
-
| HTML stream, 50,000 elements | 1 | 1,
|
|
211
|
-
| XML stream, 50,000 elements | 8 |
|
|
212
|
-
| Append/update/remove, 4,000 cycles | 1 |
|
|
201
|
+
| Load/query, 500 articles | 1 | 41.89 ms | 3.77 ms | 11.11× faster |
|
|
202
|
+
| Load/query, 5,000 articles | 1 | 184.64 ms | 41.27 ms | 4.47× faster |
|
|
203
|
+
| HTML mutations, 5,000 articles | 1 | 308.55 ms | 89.40 ms | 3.45× faster |
|
|
204
|
+
| XML load/query, 5,000 articles | 1 | 90.55 ms | 20.00 ms | 4.53× faster |
|
|
205
|
+
| Extract 16 documents × 5,000 articles | 1 | 3,615.68 ms | 557.12 ms | 6.49× faster |
|
|
206
|
+
| Extract 16 documents × 5,000 articles | 8 | 1,103.64 ms | 178.32 ms | 6.19× faster |
|
|
207
|
+
| Nested callback extraction, 8 × 500 articles | 8 | 76.75 ms | 42.52 ms | 1.81× faster |
|
|
208
|
+
| Cold extraction, 16 × 20 articles | 8 | 22.66 ms | 5.65 ms | 4.01× faster |
|
|
209
|
+
| 8 concurrent batches × 8 × 300 articles | 8 | 153.41 ms | 26.38 ms | 5.81× faster |
|
|
210
|
+
| HTML stream, 50,000 elements | 1 | 1,551.73 ms | 384.28 ms | 4.04× faster |
|
|
211
|
+
| XML stream, 50,000 elements | 8 | 168.84 ms | 108.97 ms | 1.55× faster |
|
|
212
|
+
| Append/update/remove, 4,000 cycles | 1 | 1,143.37 ms | 766.40 ms | 1.49× faster |
|
|
213
213
|
|
|
214
214
|
Cold measurements include engine import, pool initialization and the first
|
|
215
215
|
batch.
|
|
@@ -225,14 +225,14 @@ HTML. Walking the same nodes without enumerating attributes is faster in both.
|
|
|
225
225
|
Very small pages can measure either way.
|
|
226
226
|
|
|
227
227
|
**Memory.** A batch extracting 16 documents of 5,000 articles with eight CPUs
|
|
228
|
-
ended at 581 MB RSS for rusteerio and 2,
|
|
229
|
-
HTML stream of 50,000 elements at
|
|
230
|
-
load/query at 140 MB versus
|
|
231
|
-
221 MB, and the append/update/remove workload about even (
|
|
232
|
-
Linux builds use mimalloc, which keeps freed pages briefly for reuse;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
228
|
+
ended at 581 MB RSS for rusteerio and 2,523 MB for Cheerio's worker pool, the
|
|
229
|
+
HTML stream of 50,000 elements at 364 MB versus 666 MB, and the large XML
|
|
230
|
+
load/query at 140 MB versus 148 MB. The XML stream ended higher, at 236 MB versus
|
|
231
|
+
221 MB, and the append/update/remove workload about even (94 MB versus 90 MB).
|
|
232
|
+
Linux builds use mimalloc, which keeps freed pages briefly for reuse; after a
|
|
233
|
+
parse that builds at least 100,000 nodes, the parsing thread returns them to the
|
|
234
|
+
system. RSS includes initialization and resident input, and sampled peaks do not
|
|
235
|
+
establish a universal memory bound.
|
|
236
236
|
|
|
237
237
|
These results describe this VM and revision; hardware, runtime and input shape
|
|
238
238
|
affect them. See [the results](bench/results/2026-10-14/) and
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -4,7 +4,7 @@ This file preserves third-party license and attribution notices for the Rust nat
|
|
|
4
4
|
|
|
5
5
|
Generated by `node scripts/generate-notices.mjs` from `cargo metadata --locked`, crate license files, and the pinned supplemental sources recorded in `scripts/notices/sources.json`. It includes build dependencies and dependencies for all target platforms; a particular binary may use a subset. Identical notice texts are reproduced once and referenced below. The html5ever, markup5ever and html5gum crates contain local observer-hook and opt-in UTF-16 transport patches; their complete patched source and original notices are included in `native/vendor`. Other dependency source files are unmodified.
|
|
6
6
|
|
|
7
|
-
Cargo.lock SHA-256: `
|
|
7
|
+
Cargo.lock SHA-256: `b4e1749e9f6c31b8ecd8cb108285e93f365a4906f4ef04e8239959f549b7de1a`.
|
|
8
8
|
|
|
9
9
|
## Source availability
|
|
10
10
|
|
package/native/src/lib.rs
CHANGED
|
@@ -266,6 +266,7 @@ impl NativeDocument {
|
|
|
266
266
|
if arena.nodes.len() > POOL_RELEASE_NODES {
|
|
267
267
|
runtime::start_release_thread();
|
|
268
268
|
}
|
|
269
|
+
runtime::return_parse_pages(arena.nodes.len());
|
|
269
270
|
Self {
|
|
270
271
|
html: RefCell::new(None),
|
|
271
272
|
ids: RefCell::new(Vec::new()),
|
|
@@ -516,6 +517,7 @@ impl NativeDocument {
|
|
|
516
517
|
if ids.len() > POOL_RELEASE_NODES {
|
|
517
518
|
runtime::start_release_thread();
|
|
518
519
|
}
|
|
520
|
+
runtime::return_parse_pages(ids.len());
|
|
519
521
|
Self {
|
|
520
522
|
html: RefCell::new(Some(html)),
|
|
521
523
|
ids: RefCell::new(ids),
|
package/native/src/runtime.rs
CHANGED
|
@@ -183,6 +183,29 @@ static RELEASE_THREAD: OnceLock<mpsc::Sender<Box<dyn Send>>> = OnceLock::new();
|
|
|
183
183
|
/// exists, so freeing large trees does not stall JavaScript. Documents large
|
|
184
184
|
/// enough to be released later start it when they are created, because
|
|
185
185
|
/// finalizers must not create threads.
|
|
186
|
+
/// Trees with at least this many nodes return the parse's freed memory to
|
|
187
|
+
/// the system once built.
|
|
188
|
+
#[cfg(target_os = "linux")]
|
|
189
|
+
const RETURN_PAGES_NODES: usize = 100_000;
|
|
190
|
+
|
|
191
|
+
#[cfg(target_os = "linux")]
|
|
192
|
+
extern "C" {
|
|
193
|
+
fn mi_collect(force: bool);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/// Building a large tree grows and then frees big buffers, such as a node
|
|
197
|
+
/// vector that doubled several times. mimalloc keeps freed pages resident for
|
|
198
|
+
/// reuse; after a large parse, return them on the parsing thread instead.
|
|
199
|
+
pub(crate) fn return_parse_pages(nodes: usize) {
|
|
200
|
+
#[cfg(target_os = "linux")]
|
|
201
|
+
if nodes >= RETURN_PAGES_NODES {
|
|
202
|
+
// SAFETY: mimalloc's own collection frees only memory no block uses.
|
|
203
|
+
unsafe { mi_collect(true) };
|
|
204
|
+
}
|
|
205
|
+
#[cfg(not(target_os = "linux"))]
|
|
206
|
+
let _ = nodes;
|
|
207
|
+
}
|
|
208
|
+
|
|
186
209
|
pub(crate) fn start_release_thread() {
|
|
187
210
|
RELEASE_THREAD.get_or_init(|| {
|
|
188
211
|
let (sender, receiver) = mpsc::channel::<Box<dyn Send>>();
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|