on master help sign in
yet more optimization of serialize_cap_op
b13ca4dcoreyoconnor
src/Data/Terminfo/Eval.hs+7−11
@@ -61,11 +61,6 @@ apply_param_ops cap params = foldl apply_param_op params (param_ops cap)
61apply_param_op :: [CapParam] -> ParamOp -> [CapParam]
61apply_param_op :: [CapParam] -> ParamOp -> [CapParam]
62apply_param_op params IncFirstTwo = map (+ 1) params
62apply_param_op params IncFirstTwo = map (+ 1) params
63
63
64−-- | range is 0-based offset into cap_bytes and count
65−{-# INLINE ptr_at_offset #-}
66−ptr_at_offset :: CapExpression -> Word8 -> Ptr Word8
67−ptr_at_offset cap !offset = fst ( cap_bytes cap ) `plusPtr` ( fromEnum offset )
68−
69cap_expression_required_bytes :: CapExpression -> [CapParam] -> Word
64cap_expression_required_bytes :: CapExpression -> [CapParam] -> Word
70cap_expression_required_bytes cap params =
65cap_expression_required_bytes cap params =
71 let params' = apply_param_ops cap params
66 let params' = apply_param_ops cap params
@@ -77,7 +72,7 @@ cap_ops_required_bytes ops = do
77 return $ sum counts
72 return $ sum counts
78
73
79cap_op_required_bytes :: CapOp -> Eval Word
74cap_op_required_bytes :: CapOp -> Eval Word
80−cap_op_required_bytes (Bytes _ c) = return $ toEnum $ fromEnum c
75+cap_op_required_bytes (Bytes _ _ c) = return $ toEnum c
81cap_op_required_bytes DecOut = do
76cap_op_required_bytes DecOut = do
82 p <- pop
77 p <- pop
83 return $ toEnum $ length $ show p
78 return $ toEnum $ length $ show p
@@ -160,12 +155,13 @@ serialize_cap_ops :: MonadIO m => OutputBuffer -> CapOps -> EvalT m OutputBuffer
160serialize_cap_ops out_ptr ops = foldM serialize_cap_op out_ptr ops
155serialize_cap_ops out_ptr ops = foldM serialize_cap_op out_ptr ops
161
156
162serialize_cap_op :: MonadIO m => OutputBuffer -> CapOp -> EvalT m OutputBuffer
157serialize_cap_op :: MonadIO m => OutputBuffer -> CapOp -> EvalT m OutputBuffer
163−serialize_cap_op out_ptr ( Bytes offset ( W8# byte_count ) ) = do
158+serialize_cap_op out_ptr ( Bytes !offset !byte_count !next_offset ) = do
164 (cap, _) <- ask
159 (cap, _) <- ask
165− let src_ptr = ptr_at_offset cap offset
160+ let ( !start_ptr, _ ) = cap_bytes cap
166− let !i = I# ( word2Int# byte_count )
161+ !src_ptr = start_ptr `plusPtr` offset
162+ !out_ptr' = out_ptr `plusPtr` next_offset
167− liftIO $! memcpy out_ptr src_ptr ( toEnum $! i )
163+ liftIO $! memcpy out_ptr src_ptr byte_count
168− return $! out_ptr `plusPtr` i
164+ return out_ptr'
169serialize_cap_op out_ptr DecOut = do
165serialize_cap_op out_ptr DecOut = do
170 p <- pop
166 p <- pop
171 let out_str = show p
167 let out_str = show p
src/Data/Terminfo/Parse.hs+9−10
@@ -18,14 +18,13 @@ import Data.Array.Unboxed
18import Data.Monoid
18import Data.Monoid
19import Data.Word
19import Data.Word
20
20
21+import Foreign.C.Types
21import Foreign.Marshal.Array
22import Foreign.Marshal.Array
22import Foreign.Ptr
23import Foreign.Ptr
23
24
24import Text.ParserCombinators.Parsec
25import Text.ParserCombinators.Parsec
25
26
26−type BytesLength = Word8
27−type BytesOffset = Word8
28−type CapBytes = ( Ptr Word8, Word )
27+type CapBytes = ( Ptr Word8, CSize )
29
28
30data CapExpression = CapExpression
29data CapExpression = CapExpression
31 { cap_ops :: !CapOps
30 { cap_ops :: !CapOps
@@ -43,7 +42,7 @@ type CapParam = Word
43
42
44type CapOps = [CapOp]
43type CapOps = [CapOp]
45data CapOp =
44data CapOp =
46− Bytes !BytesOffset !BytesLength
45+ Bytes !Int !CSize !Int
47 | DecOut | CharOut
46 | DecOut | CharOut
48 -- This stores a 0-based index to the parameter. However the operation that implies this op is
47 -- This stores a 0-based index to the parameter. However the operation that implies this op is
49 -- 1-based
48 -- 1-based
@@ -60,7 +59,7 @@ data CapOp =
60 deriving ( Show )
59 deriving ( Show )
61
60
62instance NFData CapOp where
61instance NFData CapOp where
63− rnf (Bytes offset c) = rnf offset >| rnf c
62+ rnf ( Bytes offset count next_offset ) = rnf offset
64 rnf (PushParam !_pn) = ()
63 rnf (PushParam !_pn) = ()
65 rnf (PushValue !_v) = ()
64 rnf (PushValue !_v) = ()
66 rnf (Conditional c_expr c_parts) = rnf c_expr >| rnf c_parts
65 rnf (Conditional c_expr c_parts) = rnf c_expr >| rnf c_parts
@@ -116,7 +115,7 @@ literal_percent_parser = do
116 _ <- char '%'
115 _ <- char '%'
117 start_offset <- getState >>= return . next_offset
116 start_offset <- getState >>= return . next_offset
118 inc_offset 1
117 inc_offset 1
119− return $ BuildResults 0 [Bytes start_offset 1] []
118+ return $ BuildResults 0 [Bytes start_offset 1 1] []
120
119
121param_op_parser :: CapParser BuildResults
120param_op_parser :: CapParser BuildResults
122param_op_parser
121param_op_parser
@@ -286,11 +285,11 @@ bytes_op_parser :: CapParser BuildResults
286bytes_op_parser = do
285bytes_op_parser = do
287 bytes <- many1 $ satisfy (/= '%')
286 bytes <- many1 $ satisfy (/= '%')
288 start_offset <- getState >>= return . next_offset
287 start_offset <- getState >>= return . next_offset
289− let !c = toEnum $ length bytes
288+ let !c = length bytes
290 !s <- getState
289 !s <- getState
291 let s' = s { next_offset = start_offset + c }
290 let s' = s { next_offset = start_offset + c }
292 setState s'
291 setState s'
293− return $ BuildResults 0 [Bytes start_offset c] []
292+ return $ BuildResults 0 [Bytes start_offset ( toEnum c ) c ] []
294
293
295char_const_parser :: CapParser BuildResults
294char_const_parser :: CapParser BuildResults
296char_const_parser = do
295char_const_parser = do
@@ -301,10 +300,10 @@ char_const_parser = do
301 return $ BuildResults 0 [ PushValue char_value ] [ ]
300 return $ BuildResults 0 [ PushValue char_value ] [ ]
302
301
303data BuildState = BuildState
302data BuildState = BuildState
304− { next_offset :: Word8
303+ { next_offset :: Int
305 }
304 }
306
305
307−inc_offset :: Word8 -> CapParser ()
306+inc_offset :: Int -> CapParser ()
308inc_offset n = do
307inc_offset n = do
309 s <- getState
308 s <- getState
310 let s' = s { next_offset = next_offset s + n }
309 let s' = s { next_offset = next_offset s + n }