Skip to content

Instantly share code, notes, and snippets.

@sgrif
Created April 19, 2016 19:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgrif/24ed31f66246d71a2f7356a806ebc57a to your computer and use it in GitHub Desktop.
Save sgrif/24ed31f66246d71a2f7356a806ebc57a to your computer and use it in GitHub Desktop.
diff --git a/diesel/src/lib.rs b/diesel/src/lib.rs
index 28c60a3..18225b2 100644
--- a/diesel/src/lib.rs
+++ b/diesel/src/lib.rs
@@ -3,6 +3,7 @@
//! found in the README.
#![deny(warnings)]
#![cfg_attr(feature = "unstable", feature(specialization))]
+#![cfg_attr(all(test, feature = "unstable"), feature(test))]
#[macro_use]
mod macros;
diff --git a/diesel/src/pg/connection/mod.rs b/diesel/src/pg/connection/mod.rs
index 6066ead..634d821 100644
--- a/diesel/src/pg/connection/mod.rs
+++ b/diesel/src/pg/connection/mod.rs
@@ -239,4 +239,78 @@ mod tests {
let database_url = env::var("DATABASE_URL").unwrap();
PgConnection::establish(&database_url).unwrap()
}
+
+ #[cfg(feature = "unstable")]
+ mod benchmarks {
+ extern crate test;
+
+ use backend::Backend;
+ use expression::{SqlLiteral, sql};
+ use prelude::*;
+ use query_builder::*;
+ use super::connection;
+ use self::test::Bencher;
+
+ table! {
+ users {
+ id -> Integer,
+ name -> VarChar,
+ hair_color -> Nullable<VarChar>,
+ }
+ }
+
+ #[bench]
+ fn prepared_statement_lookup_query_builder(bm: &mut Bencher) {
+ let conn = connection();
+
+ bm.iter(|| {
+ conn.prepare_query(&users::table.as_query()).unwrap()
+ })
+ }
+
+ #[bench]
+ fn prepared_statement_lookup_raw_sql(bm: &mut Bencher) {
+ let conn = connection();
+
+ bm.iter(|| {
+ let sql = "SELECT users.id, users.name, users.hair_color FROM users";
+ conn.prepare_query(&cached_sql::<users::SqlType>(sql)).unwrap()
+ })
+ }
+
+ pub struct ForceCache<T>(T);
+
+ pub fn cached_sql<T>(query: &str) -> ForceCache<SqlLiteral<T>> {
+ ForceCache(sql(query))
+ }
+
+ impl<T, DB> QueryFragment<DB> for ForceCache<T> where
+ DB: Backend,
+ T: QueryFragment<DB>,
+ {
+ fn to_sql(&self, out: &mut DB::QueryBuilder) -> BuildQueryResult {
+ self.0.to_sql(out)
+ }
+
+ fn collect_binds(&self, out: &mut DB::BindCollector) -> QueryResult<()> {
+ self.0.collect_binds(out)
+ }
+
+ fn is_safe_to_cache_prepared(&self) -> bool {
+ true
+ }
+ }
+
+ impl<T: Query> Query for ForceCache<T> {
+ type SqlType = T::SqlType;
+ }
+
+ impl<T: QueryId> QueryId for ForceCache<T> {
+ type QueryId = T::QueryId;
+
+ fn has_static_query_id() -> bool {
+ T::has_static_query_id()
+ }
+ }
+ }
}
diff --git a/diesel/src/sqlite/connection/mod.rs b/diesel/src/sqlite/connection/mod.rs
index d6d9d10..0fa25d2 100644
--- a/diesel/src/sqlite/connection/mod.rs
+++ b/diesel/src/sqlite/connection/mod.rs
@@ -267,4 +267,84 @@ mod tests {
assert_eq!(Ok(true), query.get_result(&connection));
assert_eq!(1, connection.statement_cache.borrow().len());
}
+
+ #[cfg(feature = "unstable")]
+ mod benchmarks {
+ extern crate test;
+
+ use backend::Backend;
+ use expression::{SqlLiteral, sql};
+ use prelude::*;
+ use query_builder::*;
+ use self::test::Bencher;
+ use sqlite::SqliteConnection;
+
+ table! {
+ users {
+ id -> Integer,
+ name -> VarChar,
+ hair_color -> Nullable<VarChar>,
+ }
+ }
+
+ fn connection() -> SqliteConnection {
+ let conn = SqliteConnection::establish(":memory:").unwrap();
+ conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY NOT NULL, name VARCHAR NOT NULL, hair_color VARCHAR)").unwrap();
+ conn
+ }
+
+ #[bench]
+ fn prepared_statement_lookup_query_builder(bm: &mut Bencher) {
+ let conn = connection();
+
+ bm.iter(|| {
+ conn.prepare_query(&users::table.as_query()).unwrap()
+ })
+ }
+
+ #[bench]
+ fn prepared_statement_lookup_raw_sql(bm: &mut Bencher) {
+ let conn = connection();
+
+ bm.iter(|| {
+ let sql = "SELECT users.id, users.name, users.hair_color FROM users";
+ conn.prepare_query(&cached_sql::<users::SqlType>(sql)).unwrap()
+ })
+ }
+
+ pub struct ForceCache<T>(T);
+
+ pub fn cached_sql<T>(query: &str) -> ForceCache<SqlLiteral<T>> {
+ ForceCache(sql(query))
+ }
+
+ impl<T, DB> QueryFragment<DB> for ForceCache<T> where
+ DB: Backend,
+ T: QueryFragment<DB>,
+ {
+ fn to_sql(&self, out: &mut DB::QueryBuilder) -> BuildQueryResult {
+ self.0.to_sql(out)
+ }
+
+ fn collect_binds(&self, out: &mut DB::BindCollector) -> QueryResult<()> {
+ self.0.collect_binds(out)
+ }
+
+ fn is_safe_to_cache_prepared(&self) -> bool {
+ true
+ }
+ }
+
+ impl<T: Query> Query for ForceCache<T> {
+ type SqlType = T::SqlType;
+ }
+
+ impl<T: QueryId> QueryId for ForceCache<T> {
+ type QueryId = T::QueryId;
+
+ fn has_static_query_id() -> bool {
+ T::has_static_query_id()
+ }
+ }
+ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment