mirror of
https://github.com/joshuaclayton/unused.git
synced 2024-09-11 04:45:28 +03:00
Switch to faster/more naive implementation of String to Int conversion
Why? ==== This library converts lots of strings to positive integers (specifically, when it's parsing output from search results). Because these are always positive integers, we can make more assumptions about the data and how to parse the values. Corresponding benchmark: https://gist.github.com/joshuaclayton/767c507edf09215d08cdd79c93a5f383
This commit is contained in:
parent
4c8e8b2d72
commit
6c9912fa29
@ -7,10 +7,10 @@ module Unused.Parser.Internal
|
||||
|
||||
import Control.Monad (void)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Text.Read (readMaybe)
|
||||
import Text.Parsec
|
||||
import Text.Parsec.String (Parser)
|
||||
import Unused.Types (TermMatch(..))
|
||||
import Unused.Util (stringToInt)
|
||||
|
||||
parseTermMatches :: Parser [TermMatch]
|
||||
parseTermMatches = many1 parseTermMatch <* eof
|
||||
@ -37,10 +37,7 @@ pathParser = many1 (noneOf ":")
|
||||
|
||||
occurrenceParser :: Parser Int
|
||||
occurrenceParser =
|
||||
toInt <$> many1 digit
|
||||
where
|
||||
toInt = fromMaybe 0 . maybeInt
|
||||
maybeInt s = readMaybe s :: Maybe Int
|
||||
fromMaybe 0 . stringToInt <$> many1 digit
|
||||
|
||||
eol :: Parser String
|
||||
eol = try (string "\n\r")
|
||||
|
@ -1,12 +1,21 @@
|
||||
module Unused.Util
|
||||
( groupBy
|
||||
, stringToInt
|
||||
) where
|
||||
|
||||
import Control.Arrow ((&&&))
|
||||
import qualified Data.List as L
|
||||
import Data.Function
|
||||
import Data.Char (digitToInt, isDigit)
|
||||
|
||||
groupBy :: (Ord b) => (a -> b) -> [a] -> [(b, [a])]
|
||||
groupBy f = map (f . head &&& id)
|
||||
. L.groupBy ((==) `on` f)
|
||||
. L.sortBy (compare `on` f)
|
||||
|
||||
stringToInt :: String -> Maybe Int
|
||||
stringToInt xs
|
||||
| all isDigit xs = Just $ loop 0 xs
|
||||
| otherwise = Nothing
|
||||
where
|
||||
loop = foldl (\acc x -> acc * 10 + digitToInt x)
|
||||
|
@ -15,7 +15,7 @@ main :: IO ()
|
||||
main = hspec spec
|
||||
|
||||
spec :: Spec
|
||||
spec = parallel $
|
||||
spec = parallel $ do
|
||||
describe "groupBy" $ do
|
||||
it "groups by the result of a function" $ do
|
||||
let numbers = [1..10] :: [Int]
|
||||
@ -27,3 +27,10 @@ spec = parallel $
|
||||
|
||||
groupBy pName people `shouldBe` [("Jane", [Person "Jane" 10, Person "Jane" 20]), ("John", [Person "John" 20])]
|
||||
groupBy pAge people `shouldBe` [(10, [Person "Jane" 10]), (20, [Person "Jane" 20, Person "John" 20])]
|
||||
|
||||
describe "stringToInt" $
|
||||
it "converts a String value to Maybe Int" $ do
|
||||
stringToInt "12345678" `shouldBe` Just 12345678
|
||||
stringToInt "0" `shouldBe` Just 0
|
||||
stringToInt "10591" `shouldBe` Just 10591
|
||||
stringToInt "bad" `shouldBe` Nothing
|
||||
|
Loading…
Reference in New Issue
Block a user