Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Turn O(n^2) reverse into O(n)

This patch improves `cabal update` performance by 10x(!) on my system.
Due to this issue, `cabal update` was using an extreme amount of CPU,
while it should be I/O-bound.  The reverse was taking 79s, now it
takes 0.01s.
commit b9bd0a08fa09c6403f91422e3b23f08d339612eb 1 parent 54cf001
@nominolo authored
Showing with 1 addition and 1 deletion.
  1. +1 −1  Network/HTTP/Base.hs
View
2  Network/HTTP/Base.hs
@@ -868,7 +868,7 @@ hopefulTransfer bufOps readL strs
= readL >>=
either (\v -> return $ Left v)
(\more -> if (buf_isEmpty bufOps more)
- then return (Right ([],foldr (flip (buf_append bufOps)) (buf_empty bufOps) strs))
+ then return (Right ([], buf_concat bufOps $ reverse strs))
else hopefulTransfer bufOps readL (more:strs))
-- | A necessary feature of HTTP\/1.1

10 comments on commit b9bd0a0

@bliang

Nice

@FranklinChen

Wow. A classic "oops" in the world of monoids.

@cosql

Thumb up

@JakubOboza

i hate flip, every time i see someone removing flip from code i have to add :+1:

@naghceuz

classic

@hickford

(Saw this on Hacker News). I don't know Haskell. Could someone explain—what does the code do, how do the algorithms work, why is the second faster?

@MaxDaten

@matt-hickford: with fold you apply buf_append on every element (=n times) of strs with accumulating the result in each step. fold is O(n), buff_append (with a list like implementation) is O(n). so, together O(nO(n)) = O(nn) = O(n^2) (or: O(n*m))

buf_concat (glue list of lists together) runs in O(n). reverse runs in O(n), but isn't applied on every element. So, together in O(n) + O(n) = O(n+n) = O(n)

@amigalemming

Why is the 'reverse' needed, at all? A 'reverse' without the actual need to reverse a list often indicates that someone has assembled the data in the wrong order before.

@passy

A great explanation of this was featured on Accidentally Quadratic

Please sign in to comment.
Something went wrong with that request. Please try again.