chore: add benchmarks (#230)

This commit is contained in:
Stepan Kuzmin 2021-07-23 11:04:34 +03:00 committed by GitHub
parent 0393f1449f
commit f935db9f1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 171 additions and 46 deletions

27
.github/workflows/bench.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Benchmark
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches:
- master
jobs:
check_benchmark:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: Check benchmark
uses: actions-rs/cargo@v1
with:
command: bench

2
Cargo.lock generated
View File

@ -590,6 +590,7 @@ dependencies = [
"clap",
"criterion-plot",
"csv",
"futures",
"itertools 0.10.1",
"lazy_static",
"num-traits",
@ -602,6 +603,7 @@ dependencies = [
"serde_derive",
"serde_json",
"tinytemplate",
"tokio 1.9.0",
"walkdir",
]

View File

@ -35,8 +35,9 @@ serde_json = "1.0"
serde_yaml = "0.8"
tilejson = "0.2"
[dev-dependencies]
criterion = "0.3"
[dev-dependencies.criterion]
version = "0.3.4"
features = ["async_futures", "async_tokio", "html_reports"]
[dev-dependencies.cargo-husky]
version = "1"
@ -44,5 +45,5 @@ default-features = false
features = ["run-for-all", "prepush-hook", "run-cargo-fmt", "run-cargo-clippy", "run-cargo-test"]
[[bench]]
name = "server"
name = "sources"
harness = false

View File

@ -616,3 +616,11 @@ Make your changes, and check if all the tests are running
```shell
DATABASE_URL=postgres://postgres@localhost/db cargo test
```
You can also run benchmarks with
```shell
DATABASE_URL=postgres://postgres@localhost/db cargo bench
```
An HTML report displaying the results of the benchmark will be generated under `target/criterion/report/index.html`

View File

@ -1,37 +0,0 @@
use criterion::{criterion_group, criterion_main, Criterion};
use actix_web::dev::Service;
use actix_web::{test, App};
use martin::dev::{mock_function_sources, mock_state, mock_table_sources};
use martin::server::router;
fn criterion_benchmark(c: &mut Criterion) {
let state = test::run_on(|| mock_state(mock_table_sources(), mock_function_sources()));
let mut app = test::init_service(App::new().app_data(state).configure(router));
c.bench_function("/public.table_source/0/0/0.pbf", |b| {
b.iter(|| {
let req = test::TestRequest::get()
.uri("/public.table_source/0/0/0.pbf")
.to_request();
let future = test::run_on(|| app.call(req));
let _response = test::block_on(future).unwrap();
})
});
c.bench_function("/rpc/public.function_source/0/0/0.pbf", |b| {
b.iter(|| {
let req = test::TestRequest::get()
.uri("/rpc/public.function_source/0/0/0.pbf")
.to_request();
let future = test::run_on(|| app.call(req));
let _response = test::block_on(future).unwrap();
})
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

118
benches/sources.rs Normal file
View File

@ -0,0 +1,118 @@
use std::collections::HashMap;
use criterion::Criterion;
use criterion::{criterion_group, criterion_main};
use martin::composite_source::CompositeSource;
use martin::dev::make_pool;
use martin::function_source::FunctionSource;
use martin::source::{Source, Xyz};
use martin::table_source::TableSource;
fn mock_table_source(schema: &str, table: &str) -> TableSource {
TableSource {
id: format!("{}.{}", schema, table),
schema: schema.to_owned(),
table: table.to_owned(),
id_column: None,
geometry_column: "geom".to_owned(),
srid: 3857,
extent: Some(4096),
buffer: Some(64),
clip_geom: Some(true),
geometry_type: None,
properties: HashMap::new(),
}
}
fn mock_function_source(schema: &str, function: &str) -> FunctionSource {
FunctionSource {
id: format!("{}.{}", schema, function),
schema: schema.to_owned(),
function: function.to_owned(),
}
}
async fn get_table_source() {
let source = mock_table_source("public", "table_source");
let _tilejson = source.get_tilejson();
}
async fn get_table_source_tile() {
let pool = make_pool();
let mut connection = pool.get().unwrap();
let source = mock_table_source("public", "table_source");
let xyz = Xyz { z: 0, x: 0, y: 0 };
let _tile = source.get_tile(&mut connection, &xyz, &None).unwrap();
}
async fn get_composite_source() {
let points1 = mock_table_source("public", "points1");
let points2 = mock_table_source("public", "points2");
let source = CompositeSource {
id: "public.points1,public.points2".to_owned(),
table_sources: vec![points1, points2],
};
let _tilejson = source.get_tilejson();
}
async fn get_composite_source_tile() {
let pool = make_pool();
let mut connection = pool.get().unwrap();
let points1 = mock_table_source("public", "points1");
let points2 = mock_table_source("public", "points2");
let source = CompositeSource {
id: "public.points1,public.points2".to_owned(),
table_sources: vec![points1, points2],
};
let xyz = Xyz { z: 0, x: 0, y: 0 };
let _tile = source.get_tile(&mut connection, &xyz, &None).unwrap();
}
async fn get_function_source() {
let source = mock_function_source("public", "function_source");
let _tilejson = source.get_tilejson();
}
async fn get_function_source_tile() {
let pool = make_pool();
let mut connection = pool.get().unwrap();
let source = mock_function_source("public", "function_source");
let xyz = Xyz { z: 0, x: 0, y: 0 };
let _tile = source.get_tile(&mut connection, &xyz, &None).unwrap();
}
fn table_source(c: &mut Criterion) {
c.bench_function("get_table_source", |b| b.iter(|| get_table_source()));
c.bench_function("get_table_source_tile", |b| {
b.iter(|| get_table_source_tile())
});
}
fn composite_source(c: &mut Criterion) {
c.bench_function("get_composite_source", |b| {
b.iter(|| get_composite_source())
});
c.bench_function("get_composite_source_tile", |b| {
b.iter(|| get_composite_source_tile())
});
}
fn function_source(c: &mut Criterion) {
c.bench_function("get_function_source", |b| b.iter(|| get_function_source()));
c.bench_function("get_function_source_tile", |b| {
b.iter(|| get_function_source_tile())
});
}
criterion_group!(benches, table_source, composite_source, function_source);
criterion_main!(benches);

View File

@ -6,7 +6,7 @@ use std::rc::Rc;
use actix::{Actor, Addr, SyncArbiter};
use crate::coordinator_actor::CoordinatorActor;
use crate::db::setup_connection_pool;
use crate::db::{setup_connection_pool, Pool};
use crate::db_actor::DbActor;
use crate::function_source::{FunctionSource, FunctionSources};
use crate::server::AppState;
@ -86,17 +86,23 @@ pub fn mock_function_sources() -> Option<FunctionSources> {
Some(function_sources)
}
pub fn mock_state(
table_sources: Option<TableSources>,
function_sources: Option<FunctionSources>,
watch_mode: bool,
) -> AppState {
pub fn make_pool() -> Pool {
let connection_string: String = env::var("DATABASE_URL").unwrap();
info!("Connecting to {}", connection_string);
let pool = setup_connection_pool(&connection_string, Some(1), false).unwrap();
info!("Connected to {}", connection_string);
pool
}
pub fn mock_state(
table_sources: Option<TableSources>,
function_sources: Option<FunctionSources>,
watch_mode: bool,
) -> AppState {
let pool = make_pool();
let db = SyncArbiter::start(3, move || DbActor(pool.clone()));
let coordinator: Addr<_> = CoordinatorActor::default().start();