Skip to content

Instantly share code, notes, and snippets.

@sgrif
Created December 10, 2016 19:44
Show Gist options
  • Save sgrif/0d948fb06fab9b1f6db51c6fddf93023 to your computer and use it in GitHub Desktop.
Save sgrif/0d948fb06fab9b1f6db51c6fddf93023 to your computer and use it in GitHub Desktop.
test bench_simple_query_10_000_rows_diesel ... bench: 4,466,833 ns/iter (+/- 307,208)
test bench_simple_query_10_000_rows_postgres ... bench: 5,869,441 ns/iter (+/- 624,448)
test bench_simple_query__1_000_rows_diesel ... bench: 573,806 ns/iter (+/- 193,485)
test bench_simple_query__1_000_rows_postgres ... bench: 785,102 ns/iter (+/- 129,559)
test bench_simple_query____100_rows_diesel ... bench: 178,726 ns/iter (+/- 65,002)
test bench_simple_query____100_rows_postgres ... bench: 178,018 ns/iter (+/- 44,015)
test bench_simple_query_____10_rows_diesel ... bench: 109,076 ns/iter (+/- 45,967)
test bench_simple_query_____10_rows_postgres ... bench: 110,680 ns/iter (+/- 28,012)
test bench_simple_query______0_rows_diesel ... bench: 90,363 ns/iter (+/- 10,466)
test bench_simple_query______0_rows_postgres ... bench: 147,805 ns/iter (+/- 64,702)
test bench_simple_query______1_row_diesel ... bench: 128,458 ns/iter (+/- 56,183)
test bench_simple_query______1_row_postgres ... bench: 137,089 ns/iter (+/- 57,947)
test bench_complex_query__1_000_rows_diesel ... bench: 4,092,809 ns/iter (+/- 435,862)
test bench_complex_query__1_000_rows_postgres ... bench: 5,122,593 ns/iter (+/- 516,062)
test bench_complex_query____100_rows_diesel ... bench: 576,702 ns/iter (+/- 164,730)
test bench_complex_query____100_rows_postgres ... bench: 699,258 ns/iter (+/- 198,728)
test bench_complex_query_____10_rows_diesel ... bench: 309,001 ns/iter (+/- 126,708)
test bench_complex_query_____10_rows_postgres ... bench: 404,131 ns/iter (+/- 172,790)
test bench_complex_query______0_rows_diesel ... bench: 303,986 ns/iter (+/- 109,537)
test bench_complex_query______0_rows_postgres ... bench: 428,334 ns/iter (+/- 174,378)
test bench_complex_query______1_row_diesel ... bench: 297,736 ns/iter (+/- 86,741)
test bench_complex_query______1_row_postgres ... bench: 381,586 ns/iter (+/- 118,850)
#![feature(test, proc_macro)]
#[macro_use] extern crate diesel;
#[macro_use] extern crate diesel_codegen;
extern crate test;
infer_schema!("env:DATABASE_URL");
use self::diesel::*;
use self::diesel::pg::PgConnection;
use self::test::Bencher;
use std::env;
#[derive(Queryable, Identifiable, Associations)]
#[has_many(posts)]
pub struct User {
id: i32,
name: String,
hair_color: Option<String>,
}
#[derive(Insertable)]
#[table_name="users"]
struct NewUser {
name: String,
hair_color: Option<String>,
}
#[derive(Queryable, Identifiable, Associations)]
#[belongs_to(User)]
struct Post {
id: i32,
user_id: i32,
title: String,
body: Option<String>,
}
#[derive(Insertable)]
#[table_name="posts"]
struct NewPost<'a> {
user_id: i32,
title: &'a str,
body: Option<&'a str>,
}
fn connection() -> PgConnection {
let database_url = env::var("DATABASE_URL").unwrap();
let conn = PgConnection::establish(&database_url).unwrap();
conn.execute("TRUNCATE TABLE users, posts RESTART IDENTITY").unwrap();
conn
}
fn benchmark_simple_query(num_rows: usize, b: &mut Bencher) {
let conn = connection();
let data: Vec<_> = (0..num_rows).map(|i| {
NewUser { name: format!("User {}", i), hair_color: None }
}).collect();
assert_eq!(Ok(num_rows), insert(&data).into(users::table).execute(&conn));
b.iter(|| {
assert_eq!(num_rows, users::table.load::<User>(&conn).unwrap().len());
})
}
fn benchmark_complex_query(num_rows: usize, b: &mut Bencher) {
let conn = connection();
let mut posts = Vec::new();
let data: Vec<_> = (0..num_rows).map(|i| {
let hair_color = if i % 2 == 0 { "black" } else { "brown" };
let user = NewUser { name: format!("User {}", i), hair_color: Some(hair_color.into()) };
if i % 3 == 0 {
posts.push(NewPost {
user_id: i as i32 + 1,
title: "My first post",
body: Some("This is the body of my first post"),
})
}
user
}).collect();
assert_eq!(Ok(num_rows), insert(&data).into(users::table).execute(&conn));
assert_eq!(Ok(posts.len()), insert(&posts).into(posts::table).execute(&conn));
b.iter(|| {
use users::dsl::*;
let query = users.left_outer_join(posts::table)
.filter(hair_color.eq("black"))
.order(name.desc());
let expected_row_count = (num_rows as f64 / 2.0).ceil() as usize;
assert_eq!(expected_row_count, query.load::<(User, Option<Post>)>(&conn).unwrap().len());
})
}
#[bench]
fn bench_simple_query_10_000_rows_diesel(b: &mut Bencher) {
benchmark_simple_query(10_000, b)
}
#[bench]
fn bench_simple_query__1_000_rows_diesel(b: &mut Bencher) {
benchmark_simple_query(1_000, b)
}
#[bench]
fn bench_simple_query____100_rows_diesel(b: &mut Bencher) {
benchmark_simple_query(100, b)
}
#[bench]
fn bench_simple_query_____10_rows_diesel(b: &mut Bencher) {
benchmark_simple_query(10, b)
}
#[bench]
fn bench_simple_query______1_rows_diesel(b: &mut Bencher) {
benchmark_simple_query(1, b)
}
#[bench]
fn bench_simple_query______0_rows_diesel(b: &mut Bencher) {
benchmark_simple_query(0, b)
}
#[bench]
fn bench_complex_query__1_000_rows_diesel(b: &mut Bencher) {
benchmark_complex_query(1_000, b)
}
#[bench]
fn bench_complex_query____100_rows_diesel(b: &mut Bencher) {
benchmark_complex_query(100, b)
}
#[bench]
fn bench_complex_query_____10_rows_diesel(b: &mut Bencher) {
benchmark_complex_query(10, b)
}
#[bench]
fn bench_complex_query______1_rows_diesel(b: &mut Bencher) {
benchmark_complex_query(1, b)
}
#[bench]
fn bench_complex_query______0_rows_diesel(b: &mut Bencher) {
benchmark_complex_query(0, b)
}
#![feature(test)]
extern crate postgres;
extern crate test;
use self::postgres::*;
use self::postgres::types::ToSql;
use self::test::Bencher;
use std::env;
struct User {
id: i32,
name: String,
hair_color: Option<String>,
}
struct Post {
id: i32,
user_id: i32,
title: String,
body: Option<String>,
}
fn connection() -> Connection {
let database_url = env::var("DATABASE_URL").unwrap();
let conn = Connection::connect(&*database_url, TlsMode::None).unwrap();
conn.execute("TRUNCATE TABLE users, posts RESTART IDENTITY", &[]).unwrap();
conn
}
fn benchmark_simple_query(num_rows: usize, b: &mut Bencher) {
let conn = connection();
let mut query = "INSERT INTO users (name) VALUES ".to_string();
let mut binds = Vec::new();
for i in 0..num_rows {
if i != 0 {
query += ", ";
}
query += &format!("(${})", i + 1);
binds.push(format!("User {}", i));
}
if num_rows != 0 {
let binds_borrowed_because_reasons = binds.iter().map(|b| &*b as &ToSql).collect::<Vec<_>>();
assert_eq!(num_rows as u64, conn.execute(&query, &binds_borrowed_because_reasons).unwrap());
}
b.iter(|| {
let users = conn.query("SELECT * FROM users", &[]).unwrap().into_iter()
.map(|row| User {
id: row.get("id"),
name: row.get("name"),
hair_color: row.get("hair_color"),
}).collect::<Vec<_>>();
assert_eq!(num_rows, users.len());
})
}
fn benchmark_complex_query(num_rows: usize, b: &mut Bencher) {
let conn = connection();
let mut query = "INSERT INTO users (name, hair_color) VALUES ".to_string();
let mut posts_query = "INSERT INTO posts (user_id, title, body) VALUES ".to_string();
let mut binds = vec![];
let mut post_binds = Vec::<Box<ToSql>>::new();
for i in (0..num_rows) {
if i != 0 {
query += ", ";
}
query += &format!("(${}, ${})", binds.len()+1, binds.len()+2);
let hair_color = if i % 2 == 0 { "black" } else { "brown" };
binds.push(format!("User {}", i));
binds.push(hair_color.to_string());
if i % 3 == 0 {
let len = post_binds.len();
if len != 0 {
posts_query += ", ";
}
posts_query += &format!("(${}, ${}, ${})", len + 1, len + 2, len + 3);
post_binds.push(Box::new(i as i32 + 1));
post_binds.push(Box::new("My first post"));
post_binds.push(Box::new("This is the body of my first post"));
}
}
if num_rows != 0 {
let binds_borrowed_because_reasons_i_guess = binds.iter().map(|s| &*s as &postgres::types::ToSql).collect::<Vec<_>>();
assert_eq!(num_rows as u64, conn.execute(&query, &*binds_borrowed_because_reasons_i_guess).unwrap());
}
if post_binds.len() != 0 {
let binds_borrowed_because_reasons_i_guess = post_binds.iter().map(|s| &**s).collect::<Vec<_>>();
conn.execute(&posts_query, &*binds_borrowed_because_reasons_i_guess).unwrap();
}
b.iter(|| {
let query = "SELECT
users.id as user_id,
users.name as user_name,
users.hair_color as user_hair_color,
posts.id as post_id,
posts.user_id as post_user_id,
posts.title as post_title,
posts.body as post_body
FROM users LEFT OUTER JOIN posts ON
users.id = posts.user_id
WHERE users.hair_color = $1
ORDER BY name DESC";
let data = conn.query(query, &[&"black"]).unwrap().into_iter()
.map(|row| {
let user = User {
id: row.get("user_id"),
name: row.get("user_name"),
hair_color: row.get("user_hair_color"),
};
let post_id: Option<i32> = row.get("post_id");
let post = post_id.map(|id|
Post {
id: id,
user_id: row.get("post_user_id"),
title: row.get("post_title"),
body: row.get("post_body"),
}
);
(user, post)
})
.collect::<Vec<_>>();
let expected_row_count = (num_rows as f64 / 2.0).ceil() as usize;
assert_eq!(expected_row_count, data.len());
})
}
#[bench]
fn bench_simple_query_10_000_rows_postgres(b: &mut Bencher) {
benchmark_simple_query(10_000, b)
}
#[bench]
fn bench_simple_query__1_000_rows_postgres(b: &mut Bencher) {
benchmark_simple_query(1_000, b)
}
#[bench]
fn bench_simple_query____100_rows_postgres(b: &mut Bencher) {
benchmark_simple_query(100, b)
}
#[bench]
fn bench_simple_query_____10_rows_postgres(b: &mut Bencher) {
benchmark_simple_query(10, b)
}
#[bench]
fn bench_simple_query______1_rows_postgres(b: &mut Bencher) {
benchmark_simple_query(1, b)
}
#[bench]
fn bench_simple_query______0_rows_postgres(b: &mut Bencher) {
benchmark_simple_query(0, b)
}
#[bench]
fn bench_complex_query__1_000_rows_postgres(b: &mut Bencher) {
benchmark_complex_query(1_000, b)
}
#[bench]
fn bench_complex_query____100_rows_postgres(b: &mut Bencher) {
benchmark_complex_query(100, b)
}
#[bench]
fn bench_complex_query_____10_rows_postgres(b: &mut Bencher) {
benchmark_complex_query(10, b)
}
#[bench]
fn bench_complex_query______1_rows_postgres(b: &mut Bencher) {
benchmark_complex_query(1, b)
}
#[bench]
fn bench_complex_query______0_rows_postgres(b: &mut Bencher) {
benchmark_complex_query(0, b)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment