mirror of
https://github.com/ilyakooo0/vty.git
synced 2024-11-25 19:22:08 +03:00
perf: Improve performance for large bracketed pastes.
The current algorithm has polynomial time complexity. The new algorithm runs in linear time and is generally much more efficient because it operates on packed byte strings instead of linked lists of Char. Some timing: * 100KB: 1 second * 200KB: 2.5 seconds * 300KB: 4 seconds * 400KB: 7 seconds * 500KB: 12 seconds * 600KB: 16 seconds * 700KB: 22 seconds As we can see, it's still `O(n^2)` overall, probably because of the calls to `bracketedPasteFinished`. I'll investigate that next. The constant factor overall is much lower now: ``` Before: 2.866E-6n^3 - 1.784E-4n^2 + 0.114n - 2.622 After: -1.389E-8n^3 + 5.53E-5n^2 - 1.604E-3n + 0.273 ```
This commit is contained in:
parent
b3504fbcb0
commit
6b8d0639c3
@ -34,16 +34,9 @@ bracketedPasteFinished = isInfixOf bracketedPasteEnd
|
||||
-- 'True'.
|
||||
parseBracketedPaste :: String -> KClass
|
||||
parseBracketedPaste s =
|
||||
let (p, rest) = takeUntil (drop (length bracketedPasteStart) s) bracketedPasteEnd
|
||||
rest' = if bracketedPasteEnd `isPrefixOf` rest
|
||||
then drop (length bracketedPasteEnd) rest
|
||||
else rest
|
||||
in Valid (EvPaste $ BS8.pack p) rest'
|
||||
|
||||
takeUntil :: (Eq a) => [a] -> [a] -> ([a],[a])
|
||||
takeUntil [] _ = ([], [])
|
||||
takeUntil cs sub
|
||||
| length cs < length sub = (cs, [])
|
||||
| take (length sub) cs == sub = ([], drop (length sub) cs)
|
||||
| otherwise = let (pre, suf) = takeUntil (tail cs) sub
|
||||
in (head cs:pre, suf)
|
||||
Valid (EvPaste p) (BS8.unpack $ BS8.drop (BS8.length end) rest')
|
||||
where
|
||||
start = BS8.pack bracketedPasteStart
|
||||
end = BS8.pack bracketedPasteEnd
|
||||
(_, rest ) = BS8.breakSubstring start . BS8.pack $ s
|
||||
(p, rest') = BS8.breakSubstring end . BS8.drop (BS8.length start) $ rest
|
||||
|
Loading…
Reference in New Issue
Block a user