From 878db39080607ba476ba8d8f547ad28259efb6a9 Mon Sep 17 00:00:00 2001 From: Sibi Prabakaran Date: Fri, 5 Jun 2020 16:55:52 +0530 Subject: Optimize date plugin We avoid calling getTimeZone for each of the time the date has to be updated. Instead, it's computed once at the start and re-used for each invocation. Looking at the implementation of 'getTimeZone', we can see that it's very expensive: https://www.stackage.org/haddock/lts-15.15/time-1.9.3/src/Data-Time-LocalTime-Internal-TimeZone.html#getTimeZone It calls a C FFI each time to get the time zone (getTimeZoneCTime). This is something which we can avoid and the MR implements that. I have been using my xmobar with this patch and the result has been quite good. My xmobar CPU usage has used to hit 3~7% intermittently. With this MR, It hits only 0.7% intermittently which is nice. :-) --- changelog.md | 3 +++ src/Xmobar/Plugins/Date.hs | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index e77af85..5a02fc4 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,9 @@ _New features_ - New plugin `HandleReader` for reading data from a Haskell `Handle`. This is useful if you are running xmobar from within a Haskell program. - Build with ghc 8.10 allowed. + - Optimize date plugin by avoiding calling getTimeZone for each of + the time the date has to be updated. Instead, it's computed once + at the start and re-used for each invocation. ## Version 0.33 (February, 2020) diff --git a/src/Xmobar/Plugins/Date.hs b/src/Xmobar/Plugins/Date.hs index 1cb0596..83ca1c9 100644 --- a/src/Xmobar/Plugins/Date.hs +++ b/src/Xmobar/Plugins/Date.hs @@ -31,8 +31,16 @@ data Date = Date String String Int instance Exec Date where alias (Date _ a _) = a - run (Date f _ _) = date f rate (Date _ _ r) = r + start (Date f _ r) cb = do + t <- getCurrentTime + zone <- getTimeZone t + go zone + where + go zone = doEveryTenthSeconds r $ date zone f >>= cb -date :: String -> IO String -date format = fmap (formatTime defaultTimeLocale format) getZonedTime +date :: TimeZone -> String -> IO String +date timezone format = do + time <- getCurrentTime + let zonedTime = utcToZonedTime timezone time + pure $ formatTime defaultTimeLocale format zonedTime -- cgit v1.2.3