Skip to content

Commit 106494d

Browse files
authored
[Turbopack] migrate benchmark to new backend (#72457)
### What? Copy the benchmark to the new backend Closes PACK-3417
1 parent 171970d commit 106494d

File tree

6 files changed

+200
-2
lines changed

6 files changed

+200
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

turbopack/crates/turbo-tasks-backend/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,14 @@ turbo-tasks-hash = { workspace = true }
4747
turbo-tasks-malloc = { workspace = true, default-features = false }
4848
turbo-tasks-testing = { workspace = true }
4949

50+
[dev-dependencies]
51+
criterion = { workspace = true, features = ["async_tokio"] }
52+
5053
[build-dependencies]
5154
anyhow = { workspace = true }
5255
turbo-tasks-build = { workspace = true }
5356
vergen-gitcl = { version = "1.0.1" }
57+
58+
[[bench]]
59+
name = "mod"
60+
harness = false
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![feature(arbitrary_self_types)]
2+
#![feature(arbitrary_self_types_pointers)]
3+
4+
use criterion::{criterion_group, criterion_main, Criterion};
5+
6+
pub(crate) mod scope_stress;
7+
pub(crate) mod stress;
8+
9+
criterion_group!(
10+
name = turbo_tasks_memory_stress;
11+
config = Criterion::default();
12+
targets = stress::fibonacci, scope_stress::scope_stress
13+
);
14+
criterion_main!(turbo_tasks_memory_stress);
15+
16+
pub fn register() {
17+
turbo_tasks::register();
18+
include!(concat!(env!("OUT_DIR"), "/register_benches.rs"));
19+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
use anyhow::Result;
2+
use criterion::{BenchmarkId, Criterion};
3+
use turbo_tasks::{Completion, ReadConsistency, TryJoinIterExt, TurboTasks, Vc};
4+
use turbo_tasks_backend::{noop_backing_storage, BackendOptions, TurboTasksBackend};
5+
6+
use super::register;
7+
8+
pub fn scope_stress(c: &mut Criterion) {
9+
if matches!(
10+
std::env::var("TURBOPACK_BENCH_STRESS").ok().as_deref(),
11+
None | Some("") | Some("no") | Some("false")
12+
) {
13+
return;
14+
}
15+
16+
register();
17+
18+
let mut group = c.benchmark_group("turbo_tasks_backend_scope_stress");
19+
group.sample_size(20);
20+
21+
for size in [5, 10, 15, 20, 25, 30, 100, 200, 300] {
22+
group.throughput(criterion::Throughput::Elements(
23+
/* tasks for fib from 0 to size - 1 = */
24+
(size as u64) * (size as u64) +
25+
/* root tasks = */
26+
(2 * size as u64)
27+
- 1,
28+
));
29+
group.bench_with_input(
30+
BenchmarkId::new("rectangle", format_args!("{size} x {size}")),
31+
&size,
32+
|b, size| {
33+
let rt = tokio::runtime::Builder::new_multi_thread()
34+
.enable_all()
35+
.build()
36+
.unwrap();
37+
let size = *size;
38+
39+
b.to_async(rt).iter_with_large_drop(move || {
40+
let tt = TurboTasks::new(TurboTasksBackend::new(
41+
BackendOptions {
42+
storage_mode: None,
43+
..Default::default()
44+
},
45+
noop_backing_storage(),
46+
));
47+
async move {
48+
(0..size)
49+
.map(|a| (a, size - 1))
50+
.chain((0..size - 1).map(|b| (size - 1, b)))
51+
.map(|(a, b)| {
52+
let tt = &tt;
53+
async move {
54+
let task = tt.spawn_once_task(async move {
55+
rectangle(a, b).strongly_consistent().await?;
56+
Ok::<Vc<()>, _>(Default::default())
57+
});
58+
tt.wait_task_completion(task, ReadConsistency::Eventual)
59+
.await
60+
}
61+
})
62+
.try_join()
63+
.await
64+
.unwrap();
65+
66+
tt
67+
}
68+
})
69+
},
70+
);
71+
}
72+
}
73+
74+
/// This fills a rectagle from (0, 0) to (a, b) by
75+
/// first filling (0, 0) to (a - 1, b) and then (0, 0) to (a, b - 1) recursively
76+
#[turbo_tasks::function]
77+
async fn rectangle(a: u32, b: u32) -> Result<Vc<Completion>> {
78+
if a > 0 {
79+
rectangle(a - 1, b).await?;
80+
}
81+
if b > 0 {
82+
rectangle(a, b - 1).await?;
83+
}
84+
Ok(Completion::new())
85+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use anyhow::Result;
2+
use criterion::{BenchmarkId, Criterion};
3+
use turbo_tasks::{ReadConsistency, TryJoinIterExt, TurboTasks, Vc};
4+
use turbo_tasks_backend::{noop_backing_storage, BackendOptions, TurboTasksBackend};
5+
6+
use super::register;
7+
8+
pub fn fibonacci(c: &mut Criterion) {
9+
if matches!(
10+
std::env::var("TURBOPACK_BENCH_STRESS").ok().as_deref(),
11+
None | Some("") | Some("no") | Some("false")
12+
) {
13+
return;
14+
}
15+
16+
register();
17+
18+
let mut group = c.benchmark_group("turbo_tasks_backend_stress");
19+
group.sample_size(20);
20+
21+
for size in [100, 200, 500, 1000, 1414] {
22+
group.throughput(criterion::Throughput::Elements(
23+
/* tasks for fib from 0 to size - 1 = */
24+
size as u64 * (size as u64 + 1) / 2 +
25+
/* root task = */
26+
1,
27+
));
28+
group.bench_with_input(BenchmarkId::new("fibonacci", size), &size, |b, size| {
29+
let rt = tokio::runtime::Builder::new_multi_thread()
30+
.enable_all()
31+
.build()
32+
.unwrap();
33+
let size = *size;
34+
35+
b.to_async(rt).iter_with_large_drop(move || {
36+
let tt = TurboTasks::new(TurboTasksBackend::new(
37+
BackendOptions {
38+
storage_mode: None,
39+
..Default::default()
40+
},
41+
noop_backing_storage(),
42+
));
43+
async move {
44+
let task = tt.spawn_once_task(async move {
45+
// Number of tasks:
46+
// 1 root task
47+
// size >= 1 => + fib(0) = 1
48+
// size >= 2 => + fib(1) = 2
49+
(0..size).map(|i| fib(i, i)).try_join().await?;
50+
Ok::<Vc<()>, _>(Default::default())
51+
});
52+
tt.wait_task_completion(task, ReadConsistency::Eventual)
53+
.await
54+
.unwrap();
55+
tt
56+
}
57+
})
58+
});
59+
}
60+
}
61+
62+
#[turbo_tasks::value(transparent)]
63+
struct FibResult(u64);
64+
65+
// Number of tasks:
66+
// fib(0) = 1 tasks
67+
// fib(1) = 2 tasks
68+
// fib(n) = n + 1 tasks
69+
70+
/// Computes a fibonacci number in a recursive matter. Due to turbo-tasks this
71+
/// will result in a lot of cached tasks, so its performance is only O(n)
72+
/// (compared to non-turbo-tasks O(1.6^N)).
73+
/// This function also has a `key` parameter to allow forcing it to separate
74+
/// cache entries by using different keys.
75+
#[turbo_tasks::function]
76+
async fn fib(i: u32, key: u32) -> Result<Vc<FibResult>> {
77+
Ok(match i {
78+
0 => FibResult(1).cell(),
79+
1 => fib(0, key),
80+
_ => {
81+
let a = fib(i - 1, key);
82+
let b = fib(i - 2, key);
83+
FibResult(a.await?.wrapping_add(*b.await?)).cell()
84+
}
85+
})
86+
}

turbopack/crates/turbo-tasks-backend/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ pub fn lmdb_backing_storage(path: &Path) -> Result<LmdbBackingStorage> {
3636

3737
pub type NoopBackingStorage = KeyValueDatabaseBackingStorage<NoopKvDb>;
3838

39-
pub fn noop_backing_storage(_path: &Path) -> Result<NoopBackingStorage> {
40-
Ok(KeyValueDatabaseBackingStorage::new(NoopKvDb))
39+
pub fn noop_backing_storage() -> NoopBackingStorage {
40+
KeyValueDatabaseBackingStorage::new(NoopKvDb)
4141
}
4242

4343
pub type DefaultBackingStorage = LmdbBackingStorage;

0 commit comments

Comments
 (0)