on master help sign in
Use more compact memory representation for Version

This makes the data smaller at runtime (25% of old size + less indirection) but the real point is to make the binary representation more compact. In 100% of cases that exist right now, it goes from (3 * 64 = 192) bits to (3 * 8 = 24) bits which is ~12% of the former size. The assumption here is that no major, minor, or patch will reach 65536 because if you just did patch releases it would take one release per day for ~180 years. I would prefer to use Word8 as the runtime representation because 255 seems quite ridiculous as well, but I figured it’d be better to not have to revisit this for some bizarre case.

commit49ada5973d964057faaafbc5136515a7625c7ba2 authorEvan Czaplicki <evancz@users.noreply.github.com> dateSat 11 Feb 2017, 13:39 (10 years ago) parent17a8c76
2 files changed+43−28
src/Elm/Compiler/Version.hs+4−4 src/Elm/Package.hs+39−24
src/Elm/Compiler/Version.hs+4−4
@@ -6,14 +6,13 @@ import qualified Paths_elm_compiler as This
66import Elm.Package (Version(Version))
77
88
9−rawVersion :: [Int]
10−rawVersion =
11− Version.versionBranch This.version
9+
10+-- VERSION
1211
1312
1413version :: Version
1514version =
16− case rawVersion of
15+ case map fromIntegral (Version.versionBranch This.version) of
1716 major : minor : patch : _ ->
1817 Version major minor patch
1918
@@ -25,3 +24,4 @@ version =
2524
2625 [] ->
2726 error "could not detect version of elm-compiler you are using"
27+
src/Elm/Package.hs+39−24
@@ -145,9 +145,9 @@ instance Json.ToJSON Name where
145145
146146data Version =
147147 Version
148− { _major :: Int
149− , _minor :: Int
150− , _patch :: Int
148+ { _major :: {-# UNPACK #-} !Word16
149+ , _minor :: {-# UNPACK #-} !Word16
150+ , _patch :: {-# UNPACK #-} !Word16
151151 }
152152 deriving (Eq, Ord)
153153
@@ -165,10 +165,12 @@ bumpPatch :: Version -> Version
165165bumpPatch (Version major minor patch) =
166166 Version major minor (patch + 1)
167167
168+
168169bumpMinor :: Version -> Version
169170bumpMinor (Version major minor _patch) =
170171 Version major (minor + 1) 0
171172
173+
172174bumpMajor :: Version -> Version
173175bumpMajor (Version major _minor _patch) =
174176 Version (major + 1) 0 0
@@ -183,9 +185,9 @@ filterLatest characteristic versions =
183185 map last (List.groupBy ((==) `on` characteristic) (List.sort versions))
184186
185187
186−majorAndMinor :: Version -> (Int,Int)
188+majorAndMinor :: Version -> ( Int, Int )
187189majorAndMinor (Version major minor _patch) =
188− (major, minor)
190+ ( fromIntegral major, fromIntegral minor )
189191
190192
191193
@@ -209,34 +211,47 @@ versionToText (Version major minor patch) =
209211
210212versionFromText :: Text -> Either String Version
211213versionFromText text =
212− let
213− chunks =
214− Text.splitOn "." text
214+ case Text.splitOn "." text of
215+ [major, minor, patch] ->
216+ Version
217+ <$> toNumber major
218+ <*> toNumber minor
219+ <*> toNumber patch
215220
216− toNumber txt =
217− case Text.decimal txt of
218− Right (n, "") ->
219− Just n
221+ _ ->
222+ Left "Must have format MAJOR.MINOR.PATCH (e.g. 1.0.2)"
220223
221− _ ->
222− Nothing
223− in
224− case traverse toNumber chunks of
225− Just [major, minor, patch] ->
226− Right (Version major minor patch)
227224
228− _ ->
229− Left "Must have format MAJOR.MINOR.PATCH (e.g. 1.0.2)"
225+toNumber :: Text -> Either String Word16
226+toNumber txt =
227+ case Text.decimal txt of
228+ Right (n, "") ->
229+ Right n
230+
231+ _ ->
232+ Left "Must have format MAJOR.MINOR.PATCH (e.g. 1.0.2)"
230233
231234
232235instance Binary Version where
233236 get =
234− Version <$> get <*> get <*> get
237+ do word <- getWord8
238+ if word == 0
239+ then Version <$> get <*> get <*> get
240+ else
241+ do minor <- fromIntegral <$> getWord8
242+ patch <- fromIntegral <$> getWord8
243+ return (Version (fromIntegral word) minor patch)
235244
236245 put (Version major minor patch) =
237− do put major
238− put minor
239− put patch
246+ if major < 256 && minor < 256 && patch < 256 then
247+ do putWord8 (fromIntegral major)
248+ putWord8 (fromIntegral minor)
249+ putWord8 (fromIntegral patch)
250+ else
251+ do putWord8 0
252+ put major
253+ put minor
254+ put patch
240255
241256
242257instance Json.FromJSON Version where