New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Blocking vs async performance #48
Comments
I tried in a benchmark using criterion
source for the benchuse criterion::async_executor::{FuturesExecutor, SmolExecutor};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use glam::Vec2;
use polyanya::{Mesh, PolyanyaFile};
use rand::{rngs::StdRng, Rng, SeedableRng};
fn path_sync_vs_async(c: &mut Criterion) {
let mesh: Mesh = PolyanyaFile::from_file("meshes/aurora-merged.mesh").into();
let mesh_min_x = mesh
.vertices
.iter()
.map(|v| v.coords.x)
.fold(f32::INFINITY, |a, b| a.min(b));
let mesh_max_x = mesh
.vertices
.iter()
.map(|v| v.coords.x)
.fold(f32::NEG_INFINITY, |a, b| a.max(b));
let mesh_min_y = mesh
.vertices
.iter()
.map(|v| v.coords.y)
.fold(f32::INFINITY, |a, b| a.min(b));
let mesh_max_y = mesh
.vertices
.iter()
.map(|v| v.coords.y)
.fold(f32::NEG_INFINITY, |a, b| a.max(b));
let width = mesh_max_x - mesh_min_x;
let height = mesh_max_y - mesh_min_y;
let mut random = StdRng::from_seed([0; 32]);
c.bench_function(&"path sync".to_string(), |b| {
b.iter(|| {
let start_x = random.gen::<f32>() * width + mesh_min_x;
let start_y = random.gen::<f32>() * height + mesh_min_y;
let end_x = random.gen::<f32>() * width + mesh_min_x;
let end_y = random.gen::<f32>() * height + mesh_min_y;
black_box(mesh.path(Vec2::new(start_x, start_y), Vec2::new(end_x, end_y)))
})
});
// recreate random from the same seed
let mut random = StdRng::from_seed([0; 32]);
c.bench_function(&"path async futures".to_string(), |b| {
b.to_async(FuturesExecutor).iter(|| {
let start_x = random.gen::<f32>() * width + mesh_min_x;
let start_y = random.gen::<f32>() * height + mesh_min_y;
let end_x = random.gen::<f32>() * width + mesh_min_x;
let end_y = random.gen::<f32>() * height + mesh_min_y;
black_box(mesh.get_path(Vec2::new(start_x, start_y), Vec2::new(end_x, end_y)))
})
});
// recreate random from the same seed
let mut random = StdRng::from_seed([0; 32]);
c.bench_function(&"path async smol".to_string(), |b| {
b.to_async(SmolExecutor).iter(|| {
let start_x = random.gen::<f32>() * width + mesh_min_x;
let start_y = random.gen::<f32>() * height + mesh_min_y;
let end_x = random.gen::<f32>() * width + mesh_min_x;
let end_y = random.gen::<f32>() * height + mesh_min_y;
black_box(mesh.get_path(Vec2::new(start_x, start_y), Vec2::new(end_x, end_y)))
})
});
// recreate random from the same seed
let mut random = StdRng::from_seed([0; 32]);
c.bench_function(&"path async tokio".to_string(), |b| {
let rt = tokio::runtime::Runtime::new().unwrap();
b.to_async(rt).iter(|| {
let start_x = random.gen::<f32>() * width + mesh_min_x;
let start_y = random.gen::<f32>() * height + mesh_min_y;
let end_x = random.gen::<f32>() * width + mesh_min_x;
let end_y = random.gen::<f32>() * height + mesh_min_y;
black_box(mesh.get_path(Vec2::new(start_x, start_y), Vec2::new(end_x, end_y)))
})
});
}
criterion_group!(benches, path_sync_vs_async);
criterion_main!(benches); sync and async with the futures crate seem to have the same kind of performance, a tiny bit slower with smog, and a tiny bit faster with tokio. I don't have a good explanation, maybe tokio is better at small tasks? |
My bad! I wasn't awaiting the |
Hi! Recently did a small test to measure the performance and got very surprising results. (on aurora merged)
Can someone explain if maybe I did something wrong (see code below) or how the async version is so much faster? It doesn't look multithreaded, so how?
Thanks for the answer in advance! Very interested in the details :P
The text was updated successfully, but these errors were encountered: