git.iko.soy/Fraudik/haskell-web-wc
on main help sign in
Implement words counting
a7b796aBlinov Ilya
README.md+3−1
@@ -9,8 +9,10 @@
9## Состояние проекта
9## Состояние проекта
10
10
11[x] Первая версия, Proof of Concept. Просто работа с MultipartForm запросами, реализация wc из домашнего задания, тестирование через отправку этого README.
11[x] Первая версия, Proof of Concept. Просто работа с MultipartForm запросами, реализация wc из домашнего задания, тестирование через отправку этого README.
12−[x] Подготовлен тестовый файл: sample.txt в 1,12 ГБ. Статистики для него: 25018508 1209339403 1209339403
12+[x] Подготовлен тестовый файл: sample.txt в 1,12 ГБ. Статистики первого wc для него: 25018508 194885810 1209339403 (строки, слова, символы)
13+[x] Реализован подсчет слов, проверена корректность
13
14
14## Анализ производительности
15## Анализ производительности
15
16
161. Proof of Concept: Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.25, Maximum resident set size (kbytes): 1816
171. Proof of Concept: Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.25, Maximum resident set size (kbytes): 1816
18+2. Подсчет слов: Elapsed (wall clock) time (h:mm:ss or m:ss): 0:39.20, Maximum resident set size (kbytes): 1816
src/WordCount.hs+24−27
@@ -1,44 +1,41 @@
1−module WordCount (foldWith, foldCountElements, printSelecttedOutput, WCOutputs(..)) where
1+module WordCount (foldWith, foldCountElements, printSelecttedOutput) where
2
2
3import Streamly.Data.Fold (Fold)
3import Streamly.Data.Fold (Fold)
4−import Data.Bits
5import qualified Streamly.Data.Stream as Stream
4import qualified Streamly.Data.Stream as Stream
6−import Data.Word (Word8)
7import qualified Streamly.Data.Fold as Fold
5import qualified Streamly.Data.Fold as Fold
8import qualified Streamly.FileSystem.File as File
6import qualified Streamly.FileSystem.File as File
9import Data.Function ((&))
7import Data.Function ((&))
8+import Data.Char (ord)
9+import qualified Streamly.Unicode.Stream as Stream
10
10
11−foldWith :: Fold IO Word8 a -> String -> IO a
11+isSpace :: Char -> Bool
12−foldWith f file =
12+isSpace c = uc == 0x20 || uc - 0x9 <= 4
13− File.read file
13+ where uc = fromIntegral (ord c) :: Word
14− & Stream.fold f
15
14
16data WCOutputs =
15data WCOutputs =
17 WCOutputs {
16 WCOutputs {
18− bytesCount :: !Int
17+ charCount :: !Int
19− , charCount :: !Int
18+ , wordsCount :: !Int
20 , lineCount :: !Int
19 , lineCount :: !Int
20+ , isSpaceChar :: !Bool
21 }
21 }
22 deriving (Show)
22 deriving (Show)
23
23
24−instance Semigroup WCOutputs where
24+count :: WCOutputs -> Char -> WCOutputs
25− (WCOutputs a b c) <> (WCOutputs a' b' c') = WCOutputs (a + a') (b + b') (c + c')
25+count (WCOutputs charsAmount wordsAmount linesAmount wasSpace) char =
26−
26+ let newLinesAmount = if char == '\n' then linesAmount + 1 else linesAmount
27−instance Monoid WCOutputs where
27+ (newWordsAmount, isSpaceChar) = if isSpace char then (wordsAmount, True)
28− mempty = WCOutputs 0 0 0
28+ else (if wasSpace then wordsAmount + 1 else wordsAmount, False)
29+ in WCOutputs (charsAmount + 1) newWordsAmount newLinesAmount isSpaceChar
29
30
30−countElements :: Word8 -> WCOutputs
31+foldWith :: Fold IO Char a -> String -> IO a
31−countElements c =
32+foldWith f file =
32− WCOutputs {
33+ File.read file
33− bytesCount = 1
34+ & Stream.decodeUtf8
34− , charCount = if isContinuationByte then 0 else 1
35+ & Stream.fold f
35− , lineCount = if c == 10 then 1 else 0
36+
36− }
37− where
38− isContinuationByte = (c .&. 0xC0) == 0x80
39−
40−foldCountElements :: Fold IO Word8 WCOutputs
37+foldCountElements :: Fold IO Char WCOutputs
41−foldCountElements = Fold.foldl' (\a b -> a <> countElements b) mempty
38+foldCountElements = Fold.foldl' count (WCOutputs 0 0 0 True)
42
39
43printSelecttedOutput :: WCOutputs -> String
40printSelecttedOutput :: WCOutputs -> String
44−printSelecttedOutput output = show (lineCount output) ++ " " ++ show (charCount output) ++ " " ++ show (bytesCount output)
41+printSelecttedOutput output = show (lineCount output) ++ " " ++ show (wordsCount output) ++ " " ++ show (charCount output)