Skip to content

Instantly share code, notes, and snippets.

@jonifreeman
Created September 13, 2013 13:09
Show Gist options
  • Save jonifreeman/6550469 to your computer and use it in GitHub Desktop.
Save jonifreeman/6550469 to your computer and use it in GitHub Desktop.
Record compilation performance
// Compilation time of each commented function on my machine (as repoted by sbt console).
// **********************************************************************
// Test.scala
import shapeless._
import syntax.singleton._
object Test {
val r =
("k01" ->> 1) :: ("k02" ->> 1) :: ("k03" ->> 1) :: ("k04" ->> 1) :: ("k05" ->> 1) ::
("k06" ->> 1) :: ("k07" ->> 1) :: ("k08" ->> 1) :: ("k09" ->> 1) :: ("k10" ->> 1) ::
("k11" ->> 1) :: ("k12" ->> 1) :: ("k13" ->> 1) :: ("k14" ->> 1) :: ("k15" ->> 1) ::
("k16" ->> 1) :: ("k17" ->> 1) :: ("k18" ->> 1) :: ("k19" ->> 1) :: ("k20" ->> 1) ::
("k21" ->> 1) :: ("k22" ->> 1) :: ("k23" ->> 1) :: ("k24" ->> 1) :: ("k25" ->> 1) ::
("k26" ->> 1) :: ("k27" ->> 1) :: ("k28" ->> 1) :: ("k29" ->> 1) :: ("k30" ->> 1) ::
("k31" ->> 1) :: ("k32" ->> 1) :: ("k33" ->> 1) :: ("k34" ->> 1) :: ("k35" ->> 1) :: HNil
// r get "k01" // 1s
// r get "k02" // 4s
// r get "k03" // 7s
// r get "k04" // 10s
// r get "k05" // 12s
// r get "k10" // 21s
// r get "k20" // 30s
// This loops over every field:
// jsonless.json4s.toJSON(r) // 5s
// Cost of selecting with HList.select function is constant:
// val k02 = Witness("k02")
// r.select[record.FieldType[k02.T, Int]] // 37s
// val k20 = Witness("k20")
// r.select[record.FieldType[k20.T, Int]] // 37s
}
// Test2 compares to encoding which was used in sqltyped < 0.4.0.
// Here record is a HList of Tuple2s. Minimal implementation at the end of a gist.
// Compilation times were 3-4 times quicker.
// **********************************************************************
// Test2.scala
import shapeless.HNil
import legacyrecord._
object k01; object k02; object k03; object k04; object k05; object k06; object k07; object k08;
object k09; object k10; object k11; object k12; object k13; object k14; object k15; object k16;
object k17; object k18; object k19; object k20; object k21; object k22; object k23; object k24;
object k25; object k26; object k27; object k28; object k29; object k30; object k31; object k32;
object k33; object k34; object k35
object Test2 {
val r =
(k01 -> 1) :: (k02 -> 1) :: (k03 -> 1) :: (k04 -> 1) :: (k05 -> 1) ::
(k06 -> 1) :: (k07 -> 1) :: (k08 -> 1) :: (k09 -> 1) :: (k10 -> 1) ::
(k11 -> 1) :: (k12 -> 1) :: (k13 -> 1) :: (k14 -> 1) :: (k15 -> 1) ::
(k16 -> 1) :: (k17 -> 1) :: (k18 -> 1) :: (k19 -> 1) :: (k20 -> 1) ::
(k21 -> 1) :: (k22 -> 1) :: (k23 -> 1) :: (k24 -> 1) :: (k25 -> 1) ::
(k26 -> 1) :: (k27 -> 1) :: (k28 -> 1) :: (k29 -> 1) :: (k30 -> 1) ::
(k31 -> 1) :: (k32 -> 1) :: (k33 -> 1) :: (k34 -> 1) :: (k35 -> 1) :: HNil
// r get k01 // 1s
// r get k02 // 2s
// r get k03 // 2s
// r get k04 // 3s
// r get k05 // 3s
// r get k10 // 5s
// r get k20 // 7s
}
// **********************************************************************
// legacyrecord.scala
import shapeless._
object legacyrecord {
implicit def recordOps[R <: HList](r: R): RecordOps[R] = new RecordOps(r)
}
final class RecordOps[R <: HList](r: R) {
def lookup[K](implicit lookup: Selector[R, K]): lookup.Out = lookup(r)
def get[K](k: K)(implicit lookup0: Selector[R, K]): lookup0.Out = lookup[K]
}
@annotation.implicitNotFound(msg = "No field ${K} in record ${L}")
trait Selector[L <: HList, K] {
type Out
def apply(l : L): Out
}
trait LowPrioritySelector {
type Aux[L <: HList, K, Out0] = Selector[L, K] { type Out = Out0 }
implicit def hlistSelect[H, T <: HList, K]
(implicit st : Selector[T, K]): Aux[H :: T, K, st.Out] =
new Selector[H :: T, K] {
type Out = st.Out
def apply(l : H :: T): Out = st(l.tail)
}
}
object Selector extends LowPrioritySelector {
implicit def hlistSelect1[K, V, T <: HList]: Aux[(K, V) :: T, K, V] =
new Selector[(K, V) :: T, K] {
type Out = V
def apply(l : (K, V) :: T): Out = l.head._2
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment