From aa708f4b8a2eba0dadc87e82ec74caa862f3661a Mon Sep 17 00:00:00 2001 From: Teo Camarasu Date: Fri, 18 Oct 2024 11:42:45 +0100 Subject: [PATCH] Set NOINLINE pragmas on Generics derived default implementations of Rel8able (#346) This is an easy change that should speed up compilation for end-users without having to make any changes to their code. See Note [Generics and Inlining] --- .../20241018_112157_teofilcamarasu_try_noinline.md | 5 +++++ src/Rel8/Generic/Rel8able.hs | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 changelog.d/20241018_112157_teofilcamarasu_try_noinline.md diff --git a/changelog.d/20241018_112157_teofilcamarasu_try_noinline.md b/changelog.d/20241018_112157_teofilcamarasu_try_noinline.md new file mode 100644 index 00000000..5a30feaa --- /dev/null +++ b/changelog.d/20241018_112157_teofilcamarasu_try_noinline.md @@ -0,0 +1,5 @@ +### Added + +- Add `NOINLINE` pragmas to `Generic` derived default methods of `Rel8able`. This should speed up + compilation times. If users wish for these methods to be `INLINE`d, they can override with a + pragma in their own code. diff --git a/src/Rel8/Generic/Rel8able.hs b/src/Rel8/Generic/Rel8able.hs index 25faaead..365c17cb 100644 --- a/src/Rel8/Generic/Rel8able.hs +++ b/src/Rel8/Generic/Rel8able.hs @@ -168,6 +168,7 @@ class HTable (GColumns t) => Rel8able t where type GColumns t = G.GColumns TColumns (GRep t Expr) type GFromExprs t = t Result + {-# NOINLINE gfromColumns #-} -- See Note [Generics and Inlining] default gfromColumns :: forall context. ( SRel8able t Expr , forall table. SRel8able t (Field table) @@ -181,6 +182,7 @@ class HTable (GColumns t) => Rel8able t where SName -> sfromColumns SResult -> sfromResult + {-# NOINLINE gtoColumns #-} -- See Note [Generics and Inlining] default gtoColumns :: forall context. ( SRel8able t Expr , forall table. SRel8able t (Field table) @@ -194,10 +196,12 @@ class HTable (GColumns t) => Rel8able t where SName -> stoColumns SResult -> stoResult + {-# NOINLINE gfromResult #-} -- See Note [Generics and Inlining] default gfromResult :: (SSerialize t, GFromExprs t ~ t Result) => GColumns t Result -> GFromExprs t gfromResult = sfromResult + {-# NOINLINE gtoResult #-} -- See Note [Generics and Inlining] default gtoResult :: (SSerialize t, GFromExprs t ~ t Result) => GFromExprs t -> GColumns t Result gtoResult = stoResult @@ -274,3 +278,11 @@ stoResult = (\(_ :: proxy x) -> serialize @_ @x) . from . Record + +-- Note [Generics and Inlining] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- We want to make sure that Generics derived functions (by default) +-- do not expose their unfoldings. These are always unoptimised code and can +-- therefore be quite large, and bloat our interfaces. +-- By marking these as NOINLINE we can considerably speed up our compile times. +-- If users do want these INLINEd, they can locally override the default using a pragma.