text-format 0.3.0.0 → 0.3.0.2
raw patch · 6 files changed
+49/−25 lines, 6 filesdep ~double-conversionPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: double-conversion
API changes (from Hackage documentation)
Files
- Data/Text/Buildable.hs +3/−3
- Data/Text/Format.hs +27/−10
- Data/Text/Format/Types/Internal.hs +2/−2
- benchmarks/Benchmarks.hs +2/−0
- benchmarks/Simple.hs +12/−7
- text-format.cabal +3/−3
Data/Text/Buildable.hs view
@@ -28,7 +28,7 @@ import Data.Time.LocalTime (LocalTime, TimeOfDay, TimeZone, ZonedTime) import Data.Word (Word, Word8, Word16, Word32, Word64) import Foreign.Ptr (IntPtr, WordPtr, Ptr, ptrToWordPtr)-import qualified Data.Double.Conversion as C+import qualified Data.Double.Conversion.Text as C import qualified Data.Text as ST import qualified Data.Text.Lazy as LT @@ -108,11 +108,11 @@ build a = build (numerator a) <> singleton '/' <> build (denominator a) instance Buildable Float where- build = fromText . C.toShortest . realToFrac+ build = fromText . C.toPrecision 6 . realToFrac {-# INLINE build #-} instance Buildable Double where- build = fromText . C.toShortest+ build = fromText . C.toPrecision 6 {-# INLINE build #-} instance Buildable DiffTime where
Data/Text/Format.hs view
@@ -42,36 +42,52 @@ import Data.Text.Lazy.Builder import Prelude hiding (exp, print) import System.IO (Handle)-import qualified Data.Double.Conversion as C+import qualified Data.Double.Conversion.Text as C import qualified Data.Text as ST import qualified Data.Text.Buildable as B import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.IO as LT +-- Format strings are almost always constants, and they're expensive+-- to interpret (which we refer to as "cracking" here). We'd really+-- like to have GHC memoize the cracking of a known-constant format+-- string, so that it occurs at most once.+--+-- To achieve this, we arrange to have the cracked version of a format+-- string let-floated out as a CAF, by inlining the definitions of+-- build and functions that invoke it. This works well with GHC 7.+ -- | Render a format string and arguments to a 'Builder'. build :: Params ps => Format -> ps -> Builder-build (Format fmt) ps = zipParams (map fromText . ST.splitOn "{}" $ fmt) xs- where zipParams (f:fs) (y:ys) = f <> y <> zipParams fs ys- zipParams [f] [] = f- zipParams _ _ = error . LT.unpack $ format- "Data.Text.Format.build: {} sites, but {} parameters"- (ST.count "{}" fmt, length xs)- xs = buildParams ps+build fmt ps = zipParams fmt (crack fmt) (buildParams ps)+{-# INLINE build #-} +zipParams :: Format -> [Builder] -> [Builder] -> Builder+zipParams fmt xs = go xs+ where go (f:fs) (y:ys) = f <> y <> go fs ys+ go [f] [] = f+ go _ _ = error . LT.unpack $ format+ "Data.Text.Format.build: {} sites, but {} parameters"+ (ST.count "{}" (fromFormat fmt), length xs)++crack :: Format -> [Builder]+crack = map fromText . ST.splitOn "{}" . fromFormat+ -- | Render a format string and arguments to a 'LT.Text'. format :: Params ps => Format -> ps -> LT.Text format fmt ps = toLazyText $ build fmt ps+{-# INLINE format #-} -- | Render a format string and arguments, then print the result. print :: (MonadIO m, Params ps) => Format -> ps -> m ()-{-# SPECIALIZE print :: (Params ps) => Format -> ps -> IO () #-} print fmt ps = liftIO . LT.putStr . toLazyText $ build fmt ps+{-# INLINE print #-} -- | Render a format string and arguments, then print the result to -- the given file handle. hprint :: (MonadIO m, Params ps) => Handle -> Format -> ps -> m ()-{-# SPECIALIZE hprint :: (Params ps) => Handle -> Format -> ps -> IO () #-} hprint h fmt ps = liftIO . LT.hPutStr h . toLazyText $ build fmt ps+{-# INLINE hprint #-} -- | Pad the left hand side of a string until it reaches @k@ -- characters wide, if necessary filling with character @c@.@@ -120,3 +136,4 @@ -- is added.) hex :: Integral a => a -> Builder hex = B.build . Hex+{-# INLINE hex #-}
Data/Text/Format/Types/Internal.hs view
@@ -43,8 +43,8 @@ -- -- The underlying type is 'Text', so literal Haskell strings that -- contain Unicode characters will be correctly handled.-newtype Format = Format Text- deriving (Eq, Ord, Typeable)+newtype Format = Format { fromFormat :: Text }+ deriving (Eq, Ord, Typeable, Show) instance Monoid Format where Format a `mappend` Format b = Format (a `mappend` b)
benchmarks/Benchmarks.hs view
@@ -26,8 +26,10 @@ , bgroup "comparison" [ bench "format1" $ nf (format "hi mom {}\n") (Only (pi::Double)) , bench "printf1" $ nf (printf1 "hi mom %f\n") (pi::Double)+ , bench "show1" $ nf (\d -> "hi mom " ++ show d ++ "\n") (pi::Double) , bench "format2" $ nf (format "hi mom {} {}\n") (pi::Double, "yeah"::T.Text) , bench "printf2" $ nf (printf2 "hi mom %f %s\n") (pi::Double, "yeah"::String)+ , bench "show2" $ nf (\(d,s) -> "hi mom " ++ show d ++ " " ++ show s ++ "\n") (pi::Double, "yeah"::String) ] , bgroup "types" [ bench "unit" $ nf (format "hi") ()
benchmarks/Simple.hs view
@@ -3,6 +3,7 @@ --module Main (main) where import Control.Monad+import Data.Char import Data.Bits import System.Environment import Data.Text.Format as T@@ -41,28 +42,32 @@ L.putStr . encodeUtf8 $ t arg :: Int -> Text-arg i = T.replicate (i.&.4) "fnord"+arg i = "fnord" `T.append` (T.take (i `mod` 6) "foobar") {-# NOINLINE arg #-} one count = counting count $ \i x -> do- let t = T.format "hi mom {}\n" (Only (arg i))+ let k = arg i+ let t = {-# SCC "one/format" #-} T.format "hi mom {}\n" (Only k) L.putStr . encodeUtf8 $ t two count = counting count $ \i x -> do- let t = T.format "hi mom {} {}\n" (arg i,arg (i+1))+ let k = arg i+ let t = {-# SCC "two/format" #-} T.format "hi mom {} {}\n" (k,k) L.putStr . encodeUtf8 $ t three count = counting count $ \i x -> do- let t = T.format "hi mom {} {} {}\n" (arg i,arg (i+1),arg (i+2))+ let k = arg i+ let t = {-# SCC "three/format" #-} T.format "hi mom {} {} {}\n" (k,k,k) L.putStr . encodeUtf8 $ t four count = counting count $ \i x -> do- let t = T.format "hi mom {} {} {} {}\n" (arg i,arg (i+1),arg (i+2),arg (i+3))+ let k = arg i+ let t = {-# SCC "four/format" #-} T.format "hi mom {} {} {} {}\n" (k,k,k,k) L.putStr . encodeUtf8 $ t five count = counting count $ \i x -> do- let t = T.format "hi mom {} {} {} {} {}\n"- (arg i,arg (i+1),arg (i+2),arg (i+3),arg (i+4))+ let k = arg i+ let t = {-# SCC "five/format" #-} T.format "hi mom {} {} {} {} {}\n" (k,k,k,k,k) L.putStr . encodeUtf8 $ t dpi :: Double
text-format.cabal view
@@ -1,5 +1,5 @@ name: text-format-version: 0.3.0.0+version: 0.3.0.2 license: BSD3 license-file: LICENSE homepage: https://github.com/mailrank/text-format@@ -13,7 +13,7 @@ cabal-version: >= 1.8 build-type: Simple description:- A text formatting library optimized for ease of use and high+ A text formatting library optimized for both ease of use and high performance. extra-source-files:@@ -41,7 +41,7 @@ build-depends: array, base == 4.*,- double-conversion,+ double-conversion >= 0.2.0.0, ghc-prim, integer-gmp, old-locale,