packages feed

type-of-html 0.5.1.2 → 1.0.0.0

raw patch · 7 files changed

+124/−7 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

ChangeLog.md view
@@ -1,5 +1,12 @@ # Revision history for type-of-html +## 1.0.0.0  -- 2017-09-18++* perf increase+* more compile time optimizations+* more test cases+* more Convert instances+ ## 0.5.1.0  -- 2017-09-13  * perf increase
Readme.md view
@@ -221,6 +221,66 @@ `-O2`.  Be aware, that cabal compiles only with `-O` if you don't specify explicitly otherwise. +### Even faster++Need for speed?  Consider following advise, which is sorted in+ascending order of perf gains:++If you've got attributes or contents of length 1, use a Char.++This allows for a more efficient conversion to builder, because we+know the length at compile time.++```haskell+div_ 'a'+```++If you know for sure that you don't need escaping, use `Raw`.++This allows for a more efficient conversion to builder, because we+don't need to escape.++```haskell+div_ (Raw "a")+```++If you've got numeric attributes or contents, don't convert it to a+string.++This allows for a more efficient conversion to builder, because we+don't need to escape and don't need to handle utf8.++```haskell+div_ (42 :: Int)+```++If you know that an attribute or content is empty, use `()`.++This allows for more compile time appending and avoids two runtime+appends.++```haskell+div_ ()+```++If you know for sure a string at compile time which doesn't need+escaping, use a `Proxy Symbol`.++This allows for more compile time appending and avoids two runtime+appends, escaping and conversion to a builder.++```haskell+div_ (Proxy @"hello")+```++These techniques can have dramatic performance implications,+especially the last two. If you replace for example in the `big page+with attributes` benchmark every string with a Proxy Symbol, it'll run+in 10 ns which is 500 times faster than `blaze-html`.  Looking at core+shows that this is equivalent of directly embedding the entire+resulting html as bytestring in the binary and is therefore the+fastest possible output.+ ## Comparision to lucid and blaze-html  Advantages of `type-of-html`:
src/Html/Convert.hs view
@@ -118,6 +118,9 @@ instance Convert b => Convert (a := b) where   {-# INLINE convert #-}   convert (AT x) = convert x+instance Convert (Raw Char) where+  {-# INLINE convert #-}+  convert (Raw c) = Converted (B.charUtf8 c) instance Convert (Raw String) where   {-# INLINE convert #-}   convert (Raw x) = stringConvRaw x@@ -127,6 +130,12 @@ instance Convert (Raw TL.Text) where   {-# INLINE convert #-}   convert (Raw x) = Converted (TL.encodeUtf8Builder x)+instance Convert (Raw B.Builder) where+  {-# INLINE convert #-}+  convert (Raw x) = Converted x+instance Convert Char where+  {-# INLINE convert #-}+  convert = Converted . BP.primBounded escapeUtf8 instance Convert String where   {-# INLINE convert #-}   convert = stringConv
src/Html/Reify.hs view
@@ -61,15 +61,20 @@  instance {-# INCOHERENT #-}   ( Convert val-  ) => Renderchunks (Tagged ("" ': ss) val) where+  ) => Renderchunks (Tagged '[""] val) where   {-# INLINE renderchunks #-}   renderchunks (Tagged x)     = unConv (convert x)  instance {-# INCOHERENT #-}+  Renderchunks (Tagged '[] val) where+  {-# INLINE renderchunks #-}+  renderchunks _ = mempty++instance {-# INCOHERENT #-}   ( Convert val   , KnownSymbol s-  ) => Renderchunks (Tagged (s ': ss) val) where+  ) => Renderchunks (Tagged '[s] val) where   {-# INLINE renderchunks #-}   renderchunks (Tagged x)     = unConv (convert (Proxy @ s))
src/Html/Type.hs view
@@ -659,7 +659,9 @@   CountContent (a # b)       = CountContent a + CountContent b   CountContent (_ > b)       = CountContent b   CountContent ((_ :@: b) c) = CountContent b + CountContent c+  CountContent (a := b)      = CountContent b   CountContent ()            = 0+  CountContent (Proxy _)     = 0   CountContent _             = 1  -- | We need efficient cons, snoc and append.  This API has cons(O1)@@ -680,14 +682,13 @@  -- | Flatten a html tree of elements into a type list of tags. type family ToTypeList a :: FingerTree where-  ToTypeList (a # ())       = ToTypeList a-  ToTypeList (() # b)       = ToTypeList b   ToTypeList (a # b)        = ToTypeList a >< ToTypeList b   ToTypeList (a > ())       = 'FingerTree '[] (If (HasContent (GetInfo a)) (AppendSymbol (OpenTag a) (CloseTag a)) (OpenTag a))   ToTypeList ((a :@: b) ()) = AppendSymbol "<" (ShowElement a) <| ToTypeList b |> If (HasContent (GetInfo a)) (AppendSymbol ">" (CloseTag a)) ">"   ToTypeList (a > b)        = OpenTag a <| ToTypeList b |> CloseTag a   ToTypeList ((a :@: b) c)  = (AppendSymbol "<" (ShowElement a) <| ToTypeList b) >< (">" <| ToTypeList c |> CloseTag a)-  ToTypeList (a := b)       = 'FingerTree '[ShowAttribute a] "\""+  ToTypeList (a := b)       = ShowAttribute a <| ToTypeList b |> "\""+  ToTypeList ()             = 'FingerTree '[] ""   ToTypeList (Proxy x)      = 'FingerTree '[] x   ToTypeList x              = 'FingerTree '[""] "" 
test/Main.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TypeApplications #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeOperators    #-} {-# LANGUAGE DataKinds        #-}@@ -169,3 +170,37 @@       allT (img_A (A.id_ "a ä € 𝄞"))         shouldBe         "<img id=\"a ä € 𝄞\">"++    it "handles complex compile time documents" $ do++      allT (div_ () # i_ ())+        shouldBe+        "<div></div><i></i>"++      allT (div_ () # "a")+        shouldBe+        "<div></div>a"++      allT ("a" # i_ ())+        shouldBe+        "a<i></i>"++      allT (div_ () # i_ (Proxy @"a"))+        shouldBe+        "<div></div><i>a</i>"++      allT (div_ (Proxy @"a") # i_ ())+        shouldBe+        "<div>a</div><i></i>"++      allT (Proxy @"1" # "2")+        shouldBe+        "12"++      allT ("1" # Proxy @"2")+        shouldBe+        "12"++      allT (div_ () # td_ (Proxy @"1" # "2" # div_ () # i_A (A.id_ (Proxy @"3")) "4"))+        shouldBe+        "<div></div><td>12<div></div><i id=\"3\">4</i></td>"
type-of-html.cabal view
@@ -1,5 +1,5 @@ name:                 type-of-html-version:              0.5.1.2+version:              1.0.0.0 synopsis:             High performance type driven html generation. description:          This library makes most invalid html documents compile time errors and uses advanced type level features to realise compile time computations. license:              BSD3@@ -37,7 +37,7 @@   type:               exitcode-stdio-1.0   main-is:            Main.hs   hs-source-dirs:     test-  ghc-options:        -Wall+  ghc-options:        -Wall -O0   default-language:   Haskell2010   build-depends:      base >= 4.10 && < 4.11                     , type-of-html