timestats 0.1.0 → 0.1.1
raw patch · 6 files changed
+85/−15 lines, 6 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Debug.TimeStats.Internal: formatIntWithSeparator :: Char -> Int -> ShowS
Files
- CHANGELOG.md +5/−1
- README.md +12/−4
- src/Debug/TimeStats.hs +2/−1
- src/Debug/TimeStats/Internal.hs +27/−0
- tests/Main.hs +36/−0
- timestats.cabal +3/−9
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for timestats -## 0.1.0 -- 2022-07-12+## 0.1.1 -- 2023-11-05++* Format counts with a thousand separator++## 0.1.0 -- 2022-07-15 * First version.
README.md view
@@ -1,9 +1,9 @@ # timestats -This library implements time profiling by focusing on-simplicity of use. Most programs should be possible to analyze by-instrumenting the code with a few calls and then building and-running the application as usual.+This is a simple library for profiling time that can help when more+sophisticated tools aren't available or needed. Most programs should+be possible to analyze by instrumenting the code with a few calls+and then building and running the application as usual. This library associates fragments of a program with labels, and measures the execution time of these fragments using the function@@ -13,6 +13,11 @@ using the same label) are aggregated and reported at chosen times of the execution. +The [announcement post][timestats-announcement] contains additional+motivation.++[timestats-announcement]: https://www.tweag.io/blog/2022-07-28-timestats/+ ## Usage ```Haskell@@ -46,3 +51,6 @@ `DEBUG_TIMESTATS_ENABLE` to any value ahead of invoking any function in [Debug.TimeStats](src/Debug/TimeStats.hs). +See the [API documentation][timestats-hackage] for further details.++[timestats-hackage]: https://hackage.haskell.org/package/timestats
src/Debug/TimeStats.hs view
@@ -40,6 +40,7 @@ import qualified Data.Text as Text import qualified Data.Text.IO as Text import Data.Word (Word64)+import Debug.TimeStats.Internal (formatIntWithSeparator) import GHC.Clock (getMonotonicTimeNSec) import Text.Printf (printf) import System.Environment (lookupEnv)@@ -190,7 +191,7 @@ formatTimeStats :: TimeStats -> (String, String) formatTimeStats t = ( printf "%.3f" (fromIntegral (timeStat t) / 1e9 :: Double)- , printf "%d" (countStat t)+ , formatIntWithSeparator '_' (countStat t) "" ) -- At the time of this writing printf can't render to 'Text'.
+ src/Debug/TimeStats/Internal.hs view
@@ -0,0 +1,27 @@+-- | Internal functions for timestats+module Debug.TimeStats.Internal+ ( formatIntWithSeparator+ ) where+++-- | Formats an int with a thousand separator.+--+-- For instance+--+-- > formatIntWithSeparator '_' 123456789 "a" == "123_456_789a"+--+formatIntWithSeparator :: Char -> Int -> ShowS+formatIntWithSeparator sep x0 s0 =+ if x0 >= 0 then go x0 s0 else '-' : go (-x0) s0+ where+ -- precondition: x >= 0+ go x s =+ let (d, m) = divMod x 1000+ in if d <= 0 then shows m s+ else go d $ sep : pad999 m ++ shows m s++ -- precondition: 0 <= m && m <= 999+ pad999 m+ | m < 10 = "00"+ | m < 100 = "0"+ | otherwise = ""
tests/Main.hs view
@@ -4,6 +4,7 @@ import Control.Monad (unless) import qualified Data.Text.IO as Text import qualified Debug.TimeStats as TimeStats+import qualified Debug.TimeStats.Internal as Internal import System.Environment (setEnv) import System.Exit (exitFailure) @@ -12,6 +13,11 @@ main :: IO () main = do+ testMeasureM+ testFormatNatWithSeparator++testMeasureM :: IO ()+testMeasureM = do setEnv "DEBUG_TIMESTATS_ENABLE" "1" _ <- TimeStats.measureM "fib" $ evaluate (fib 21) _ <- TimeStats.measureM "fib2" $ evaluate (fib 20)@@ -29,3 +35,33 @@ eqStats xs ys = length xs == length ys && and (zipWith eqStat xs ys) eqStat (lbl0, ts0) (lbl1, ts1) = lbl0 == lbl1 && TimeStats.countStat ts0 == TimeStats.countStat ts1++testFormatNatWithSeparator :: IO ()+testFormatNatWithSeparator = do+ testCase 123456789 "123_456_789"+ testCase 23456789 "23_456_789"+ testCase 3456789 "3_456_789"+ testCase 456789 "456_789"+ testCase 56789 "56_789"+ testCase 6789 "6_789"+ testCase 789 "789"+ testCase 89 "89"+ testCase 9 "9"+ testCase 0 "0"+ testCase (-123456789) "-123_456_789"+ testCase (-23456789) "-23_456_789"+ testCase (-3456789) "-3_456_789"+ testCase (-456789) "-456_789"+ testCase (-56789) "-56_789"+ testCase (-6789) "-6_789"+ testCase (-789) "-789"+ testCase (-89) "-89"+ testCase (-9) "-9"+ where+ testCase i expected = do+ let actual = Internal.formatIntWithSeparator '_' i "a"+ unless (actual == expected ++ "a") $ do+ putStrLn $ "unexpected output of formatIntWithSeparator:"+ putStrLn $ "expected: " ++ show (expected ++ "a")+ putStrLn $ " actual: " ++ show actual+ exitFailure
timestats.cabal view
@@ -1,10 +1,8 @@ cabal-version: 2.4 name: timestats-version: 0.1.0+version: 0.1.1 synopsis: A library for profiling time in Haskell applications-description: A simple library for profiling time that can help when more- sophisticated tools aren't available or needed. homepage: https://github.com/tweag/timestats bug-reports: https://github.com/tweag/timestats/issues@@ -19,11 +17,6 @@ CHANGELOG.md README.md -source-repository head- type: git- location: https://github.com/tweag/timestats- tag: v0.1.0- flag devel default: False manual: True@@ -32,7 +25,8 @@ library exposed-modules: Debug.TimeStats- build-depends: base >=4.14 && <5, containers, text+ Debug.TimeStats.Internal+ build-depends: base <5, containers, text hs-source-dirs: src default-language: Haskell2010 if flag(devel)