[Turbopack] migrate benchmark to new backend (#72457)

### What?

Copy the benchmark to the new backend

Closes PACK-3417
This commit is contained in:
Tobias Koppers
2024-11-13 08:39:52 +01:00
committed by GitHub
parent 171970d1c6
commit 106494de3d
6 changed files with 200 additions and 2 deletions
Generated
+1
View File
@@ -8375,6 +8375,7 @@ dependencies = [
"async-trait",
"auto-hash-map",
"byteorder",
"criterion",
"dashmap 6.1.0",
"either",
"hashbrown 0.14.5",
@@ -47,7 +47,14 @@ turbo-tasks-hash = { workspace = true }
turbo-tasks-malloc = { workspace = true, default-features = false }
turbo-tasks-testing = { workspace = true }
[dev-dependencies]
criterion = { workspace = true, features = ["async_tokio"] }
[build-dependencies]
anyhow = { workspace = true }
turbo-tasks-build = { workspace = true }
vergen-gitcl = { version = "1.0.1" }
[[bench]]
name = "mod"
harness = false
@@ -0,0 +1,19 @@
#![feature(arbitrary_self_types)]
#![feature(arbitrary_self_types_pointers)]
use criterion::{criterion_group, criterion_main, Criterion};
pub(crate) mod scope_stress;
pub(crate) mod stress;
criterion_group!(
name = turbo_tasks_memory_stress;
config = Criterion::default();
targets = stress::fibonacci, scope_stress::scope_stress
);
criterion_main!(turbo_tasks_memory_stress);
pub fn register() {
turbo_tasks::register();
include!(concat!(env!("OUT_DIR"), "/register_benches.rs"));
}
@@ -0,0 +1,85 @@
use anyhow::Result;
use criterion::{BenchmarkId, Criterion};
use turbo_tasks::{Completion, ReadConsistency, TryJoinIterExt, TurboTasks, Vc};
use turbo_tasks_backend::{noop_backing_storage, BackendOptions, TurboTasksBackend};
use super::register;
pub fn scope_stress(c: &mut Criterion) {
if matches!(
std::env::var("TURBOPACK_BENCH_STRESS").ok().as_deref(),
None | Some("") | Some("no") | Some("false")
) {
return;
}
register();
let mut group = c.benchmark_group("turbo_tasks_backend_scope_stress");
group.sample_size(20);
for size in [5, 10, 15, 20, 25, 30, 100, 200, 300] {
group.throughput(criterion::Throughput::Elements(
/* tasks for fib from 0 to size - 1 = */
(size as u64) * (size as u64) +
/* root tasks = */
(2 * size as u64)
- 1,
));
group.bench_with_input(
BenchmarkId::new("rectangle", format_args!("{size} x {size}")),
&size,
|b, size| {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
let size = *size;
b.to_async(rt).iter_with_large_drop(move || {
let tt = TurboTasks::new(TurboTasksBackend::new(
BackendOptions {
storage_mode: None,
..Default::default()
},
noop_backing_storage(),
));
async move {
(0..size)
.map(|a| (a, size - 1))
.chain((0..size - 1).map(|b| (size - 1, b)))
.map(|(a, b)| {
let tt = &tt;
async move {
let task = tt.spawn_once_task(async move {
rectangle(a, b).strongly_consistent().await?;
Ok::<Vc<()>, _>(Default::default())
});
tt.wait_task_completion(task, ReadConsistency::Eventual)
.await
}
})
.try_join()
.await
.unwrap();
tt
}
})
},
);
}
}
/// This fills a rectagle from (0, 0) to (a, b) by
/// first filling (0, 0) to (a - 1, b) and then (0, 0) to (a, b - 1) recursively
#[turbo_tasks::function]
async fn rectangle(a: u32, b: u32) -> Result<Vc<Completion>> {
if a > 0 {
rectangle(a - 1, b).await?;
}
if b > 0 {
rectangle(a, b - 1).await?;
}
Ok(Completion::new())
}
@@ -0,0 +1,86 @@
use anyhow::Result;
use criterion::{BenchmarkId, Criterion};
use turbo_tasks::{ReadConsistency, TryJoinIterExt, TurboTasks, Vc};
use turbo_tasks_backend::{noop_backing_storage, BackendOptions, TurboTasksBackend};
use super::register;
pub fn fibonacci(c: &mut Criterion) {
if matches!(
std::env::var("TURBOPACK_BENCH_STRESS").ok().as_deref(),
None | Some("") | Some("no") | Some("false")
) {
return;
}
register();
let mut group = c.benchmark_group("turbo_tasks_backend_stress");
group.sample_size(20);
for size in [100, 200, 500, 1000, 1414] {
group.throughput(criterion::Throughput::Elements(
/* tasks for fib from 0 to size - 1 = */
size as u64 * (size as u64 + 1) / 2 +
/* root task = */
1,
));
group.bench_with_input(BenchmarkId::new("fibonacci", size), &size, |b, size| {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
let size = *size;
b.to_async(rt).iter_with_large_drop(move || {
let tt = TurboTasks::new(TurboTasksBackend::new(
BackendOptions {
storage_mode: None,
..Default::default()
},
noop_backing_storage(),
));
async move {
let task = tt.spawn_once_task(async move {
// Number of tasks:
// 1 root task
// size >= 1 => + fib(0) = 1
// size >= 2 => + fib(1) = 2
(0..size).map(|i| fib(i, i)).try_join().await?;
Ok::<Vc<()>, _>(Default::default())
});
tt.wait_task_completion(task, ReadConsistency::Eventual)
.await
.unwrap();
tt
}
})
});
}
}
#[turbo_tasks::value(transparent)]
struct FibResult(u64);
// Number of tasks:
// fib(0) = 1 tasks
// fib(1) = 2 tasks
// fib(n) = n + 1 tasks
/// Computes a fibonacci number in a recursive matter. Due to turbo-tasks this
/// will result in a lot of cached tasks, so its performance is only O(n)
/// (compared to non-turbo-tasks O(1.6^N)).
/// This function also has a `key` parameter to allow forcing it to separate
/// cache entries by using different keys.
#[turbo_tasks::function]
async fn fib(i: u32, key: u32) -> Result<Vc<FibResult>> {
Ok(match i {
0 => FibResult(1).cell(),
1 => fib(0, key),
_ => {
let a = fib(i - 1, key);
let b = fib(i - 2, key);
FibResult(a.await?.wrapping_add(*b.await?)).cell()
}
})
}
@@ -36,8 +36,8 @@ pub fn lmdb_backing_storage(path: &Path) -> Result<LmdbBackingStorage> {
pub type NoopBackingStorage = KeyValueDatabaseBackingStorage<NoopKvDb>;
pub fn noop_backing_storage(_path: &Path) -> Result<NoopBackingStorage> {
Ok(KeyValueDatabaseBackingStorage::new(NoopKvDb))
pub fn noop_backing_storage() -> NoopBackingStorage {
KeyValueDatabaseBackingStorage::new(NoopKvDb)
}
pub type DefaultBackingStorage = LmdbBackingStorage;