{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} import Criterion ( bench, bgroup, env, nf ) import Criterion.Main ( defaultMain ) import qualified Data.ByteString as B import qualified Data.Text as T import qualified "string-interpolate" Data.String.Interpolate as SI import qualified "interpolate" Data.String.Interpolate.IsString as I -- import "Interpolation" Data.String.Interpolation as N import "formatting" Formatting ( (%) ) import qualified "formatting" Formatting as F import qualified "formatting" Formatting.ShortFormatters as F import "interpolatedstring-perl6" Text.InterpolatedString.Perl6 as P import qualified "neat-interpolation" NeatInterpolation as NI import Test.QuickCheck -------------------------------------------------------------------------------- -- Interpolating Strings -------------------------------------------------------------------------------- stringSI :: String -> String stringSI str = [SI.i|A fine day to die, #{str}.|] stringI :: String -> String stringI str = [I.i|A fine day to die, #{str}.|] stringF :: String -> String stringF = F.formatToString ("A fine day to die, " % F.s % ".") -- stringN :: String -> String -- stringN s = [str|A fine day to die, $s$.|] stringP :: String -> String stringP str = [qc|A fine day to die, {str}.|] -------------------------------------------------------------------------------- -- Interpolating Text -------------------------------------------------------------------------------- textSI :: T.Text -> T.Text textSI t = [SI.i|A fine day to die, #{t}.|] textI :: T.Text -> T.Text textI t = [I.i|A fine day to die, #{t}.|] textF :: T.Text -> T.Text textF = F.sformat ("A fine day to die, " % F.st % ".") -- textN :: T.Text -> T.Text -- textN t = [str|A fine day to die, $t$.|] textP :: T.Text -> T.Text textP t = [qc|A fine day to die, {t}.|] textNI :: T.Text -> T.Text textNI t = [NI.text|A fine day to die, $t.|] -------------------------------------------------------------------------------- -- Interpolating ByteString -------------------------------------------------------------------------------- byteStringSI :: B.ByteString -> B.ByteString byteStringSI b = [SI.i|A fine day to die, #{b}.|] byteStringI :: B.ByteString -> B.ByteString byteStringI b = [I.i|A fine day to die, #{b}.|] -- byteStringN :: B.ByteString -> B.ByteString -- byteStringN b = [str|A fine day to die, $b$.|] byteStringP :: B.ByteString -> B.ByteString byteStringP b = [qc|A fine day to die, {b}.|] -------------------------------------------------------------------------------- -- Multiple String interpolations -------------------------------------------------------------------------------- multiStringSI :: (Int, String, Bool) -> String multiStringSI (x, y, z) = [SI.i| foo #{x} bar #{y} baz #{z} quux |] multiStringI :: (Int, String, Bool) -> String multiStringI (x, y, z) = [I.i| foo #{x} bar #{y} baz #{z} quux |] multiStringF :: (Int, String, Bool) -> String multiStringF (x, y, z) = F.formatToString (" foo " % F.d % " bar " % F.s % " baz " % F.sh % " quux ") x y z -- multiStringN :: (Int, String, Bool) -> String -- multiStringN (x, y, z) = [str| foo $:x$ bar $y$ baz $:z$ quux |] multiStringP :: (Int, String, Bool) -> String multiStringP (x, y, z) = [qc| foo {x} bar {y} baz {z} quux |] -------------------------------------------------------------------------------- -- Multiple Text interpolations -------------------------------------------------------------------------------- multiTextSI :: (Int, T.Text, Bool) -> T.Text multiTextSI (x, y, z) = [SI.i| foo #{x} bar #{y} baz #{z} quux |] multiTextI :: (Int, T.Text, Bool) -> T.Text multiTextI (x, y, z) = [I.i| foo #{x} bar #{y} baz #{z} quux |] multiTextF :: (Int, T.Text, Bool) -> T.Text multiTextF (x, y, z) = F.sformat (" foo " % F.d % " bar " % F.st % " baz " % F.sh % " quux ") x y z -- multiTextN :: (Int, T.Text, Bool) -> T.Text -- multiTextN (x, y, z) = [str| foo $:x$ bar $y$ baz $:z$ quux |] multiTextP :: (Int, T.Text, Bool) -> T.Text multiTextP (x, y, z) = [qc| foo {x} bar {y} baz {z} quux |] multiTextNI :: (Int, T.Text, Bool) -> T.Text multiTextNI (x, y, z) = let x' = T.pack $ show x z' = T.pack $ show z in [NI.text| foo $x' bar $y baz $z' quux |] -------------------------------------------------------------------------------- -- Multiple ByteString interpolations -------------------------------------------------------------------------------- multiByteStringSI :: (Int, B.ByteString, Bool) -> B.ByteString multiByteStringSI (x, y, z) = [SI.i| foo #{x} bar #{y} baz #{z} quux |] multiByteStringI :: (Int, B.ByteString, Bool) -> B.ByteString multiByteStringI (x, y, z) = [I.i| foo #{x} bar #{y} baz #{z} quux |] -- multiByteStringN :: (Int, B.ByteString, Bool) -> B.ByteString -- multiByteStringN (x, y, z) = [str| foo $:x$ bar $y$ baz $:z$ quux |] multiByteStringP :: (Int, B.ByteString, Bool) -> B.ByteString multiByteStringP (x, y, z) = [qc| foo {x} bar {y} baz {z} quux |] main :: IO () main = defaultMain $ [ bgroup "Small Strings Bench" $ [ bench "string-interpolate" $ nf stringSI "William" , bench "interpolate" $ nf stringI "William" , bench "formatting" $ nf stringF "William" -- , bench "Interpolation" $ nf stringN "William" , bench "interpolatedstring-perl6" $ nf stringP "William" ] , bgroup "Small Text Bench" $ [ bench "string-interpolate" $ nf textSI "William" , bench "interpolate" $ nf textI "William" , bench "formatting" $ nf textF "William" -- , bench "Interpolation" $ nf textN "William" , bench "interpolatedstring-perl6" $ nf textP "William" , bench "neat-interpolation" $ nf textNI "William" ] , bgroup "Small ByteString Bench" $ [ bench "string-interpolate" $ nf byteStringSI "William" , bench "interpolate" $ nf byteStringI "William" -- "formatting" doesn't support ByteStrings. -- , bench "Interpolation" $ nf byteStringN "William" , bench "interpolatedstring-perl6" $ nf byteStringP "William" ] , bgroup "Multiple Interpolations String Bench" $ [ bench "string-interpolate" $ nf multiStringSI (42, "CATALLAXY", True) , bench "interpolate" $ nf multiStringI (42, "CATALLAXY", True) , bench "formatting" $ nf multiStringF (42, "CATALLAXY", True) -- , bench "Interpolation" $ nf multiStringN (42, "CATALLAXY", True) , bench "interpolatedstring-perl6" $ nf multiStringP (42, "CATALLAXY", True) ] , bgroup "Multiple Interpolations Text Bench" $ [ bench "string-interpolate" $ nf multiTextSI (42, "CATALLAXY", True) , bench "interpolate" $ nf multiTextI (42, "CATALLAXY", True) , bench "formatting" $ nf multiTextF (42, "CATALLAXY", True) -- , bench "Interpolation" $ nf multiTextN (42, "CATALLAXY", True) , bench "interpolatedstring-perl6" $ nf multiTextP (42, "CATALLAXY", True) , bench "neat-interpolation" $ nf multiTextNI (42, "CATALLAXY", True) ] , bgroup "Multiple Interpolations ByteString Bench" $ [ bench "string-interpolate" $ nf multiByteStringSI (42, "CATALLAXY", True) , bench "interpolate" $ nf multiByteStringI (42, "CATALLAXY", True) -- "formatting" doesn't support ByteStrings. -- , bench "Interpolation" $ nf multiByteStringN (42, "CATALLAXY", True) , bench "interpolatedstring-perl6" $ nf multiByteStringP (42, "CATALLAXY", True) ] , env largeishText $ \ ~t -> bgroup "Largeish Text Bench" $ [ bench "string-interpolate" $ nf textSI t , bench "interpolate" $ nf textI t , bench "formatting" $ nf textF t -- , bench "Interpolation" $ nf textN t , bench "interpolatedstring-perl6" $ nf textP t , bench "neat-interpolation" $ nf textNI t ] , env largeishByteString $ \ ~bs -> bgroup "Largeish ByteString Bench" $ [ bench "string-interpolate" $ nf byteStringSI bs , bench "interpolate" $ nf byteStringI bs -- "formatting" doesn't support ByteStrings. -- , bench "Interpolation" $ nf byteStringN bs , bench "interpolatedstring-perl6" $ nf byteStringP bs ] ] largeishText :: IO T.Text largeishText = generate $ T.pack <$> Prelude.take 100000 <$> infiniteListOf arbitrary largeishByteString :: IO B.ByteString largeishByteString = generate $ B.pack <$> Prelude.take 100000 <$> infiniteListOf arbitrary