Skip to content

Instantly share code, notes, and snippets.

@sgrif
Created November 30, 2015 21:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sgrif/da762c08f9a567c80d44 to your computer and use it in GitHub Desktop.
Save sgrif/da762c08f9a567c80d44 to your computer and use it in GitHub Desktop.
test bench_diesel::query_10k_rows_diesel ... bench: 7,016,479 ns/iter (+/- 595,648)
test bench_diesel::query_one_row_diesel ... bench: 124,106 ns/iter (+/- 74,952)
test bench_postgres::query_10k_rows_postgres ... bench: 9,834,664 ns/iter (+/- 779,528)
test bench_postgres::query_one_row_postgres ... bench: 186,260 ns/iter (+/- 89,780)
#![feature(custom_derive, plugin, custom_attribute, test)]
#![plugin(diesel_codegen)]
#[macro_use]
extern crate diesel;
extern crate postgres;
extern crate test;
#[insertable_into(users)]
pub struct NewUser {
name: String,
hair_color: Option<String>
}
impl NewUser {
pub fn new(name: String, hair_color: Option<String>) -> Self {
NewUser {
name: name,
hair_color: hair_color,
}
}
}
table! {
users {
id -> Serial,
name -> VarChar,
hair_color -> Nullable<VarChar>,
created_at -> Timestamp,
}
}
mod bench_diesel {
use super::*;
use diesel::*;
use diesel::query_builder::insert;
#[derive(Queriable)]
pub struct User {
id: i32,
name: String,
hair_color: Option<String>,
created_at: data_types::PgTimestamp,
}
#[bench]
fn query_one_row_diesel(b: &mut test::Bencher) {
let conn = Connection::establish(env!("DATABASE_URL")).unwrap();
conn.begin_test_transaction();
conn.execute("CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
hair_color VARCHAR,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
)").unwrap();
insert(&NewUser::new("Sean".into(), Some("black".into()))).into(users::table)
.execute(&conn).unwrap();
b.iter(|| {
users::table.first::<User>(&conn).unwrap()
})
}
#[bench]
fn query_10k_rows_diesel(b: &mut test::Bencher) {
let conn = Connection::establish(env!("DATABASE_URL")).unwrap();
conn.begin_test_transaction();
conn.execute("CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
hair_color VARCHAR,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
)").unwrap();
let data: Vec<_> = (0..10_000).map(|i| {
NewUser::new(format!("User {}", i), Some(format!("hair color {}", i)))
}).collect();
insert(&data).into(users::table).execute(&conn).unwrap();
b.iter(|| {
users::table.load(&conn).unwrap().collect::<Vec<User>>()
})
}
}
mod bench_postgres {
use super::*;
use postgres::*;
use postgres::types::ToSql;
extern crate time;
pub struct User {
id: i32,
name: String,
hair_color: Option<String>,
created_at: time::Timespec,
}
#[bench]
fn query_one_row_postgres(b: &mut test::Bencher) {
let conn = Connection::connect(env!("DATABASE_URL"), &SslMode::None).unwrap();
let trans = conn.transaction().unwrap();
trans.execute("CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
hair_color VARCHAR,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
)", &[]).unwrap();
trans.execute("INSERT INTO users (name, hair_color) VALUES ($1, $2)",
&[&"Sean", &"black"]);
b.iter(|| {
let stmt = conn.prepare("SELECT * FROM users LIMIT 1").unwrap();
let rows = stmt.query(&[]).unwrap(); // postgres forces assigning this to a variable...
let row = rows.get(0);
User {
id: row.get("id"),
name: row.get("name"),
hair_color: row.get("hair_color"),
created_at: row.get("created_at"),
}
})
}
#[bench]
fn query_10k_rows_postgres(b: &mut test::Bencher) {
let conn = Connection::connect(env!("DATABASE_URL"), &SslMode::None).unwrap();
let trans = conn.transaction().unwrap();
trans.execute("CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
hair_color VARCHAR,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
)", &[]).unwrap();
let mut query = "INSERT INTO users (name, hair_color) VALUES ".to_string();
let data: Vec<_> = (0..10_000).flat_map(|i| {
if i != 0 {
query.push_str(", ");
}
query.push_str(&format!("(${}, ${})", i * 2 + 1, i * 2 + 2));
vec![format!("User {}", i), format!("hair color {}", i)]
}).collect();
trans.execute(&query, &data.iter().map(|d| d as &ToSql).collect::<Vec<_>>()).unwrap();
b.iter(|| {
let stmt = conn.prepare("SELECT * FROM users").unwrap();
stmt.query(&[]).unwrap().iter().map(|row| {
User {
id: row.get("id"),
name: row.get("name"),
hair_color: row.get("hair_color"),
created_at: row.get("created_at"),
}
}).collect::<Vec<_>>()
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment