TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

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

175 pointsby ddinhover 11 years ago

10 comments

drostieover 11 years ago
Explanation:<p>bufOps is a dictionary which holds a bunch of functions accessed with the getters on it. For the sake of this comment, we can concretize and use (buf_empty bufOps) as [] and (buf_append bufOps) as ++.<p>This code then essentially performs:<p><pre><code> foldr (flip (++)) [] xs </code></pre> Which, if you look up the definition of foldr, is:<p><pre><code> ((([] ++ xN) ++ ... ) ++ x2) ++ x1 </code></pre> And a definition of ++ is of course:<p><pre><code> [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) </code></pre> This means that for lists of this sort a ++ b runs in time O(length a), because it has to descend down the leftmost list to find the empty list -- only once it finds [] can it &quot;work its way backwards&quot; to append elements from a onto b.<p>If each of the x1, x2, ... xN has m elements, then we do 0 + m + 2m + ... + N m = m * N * (N + 1) &#x2F; 2 operations. Each ++ will do about N operations and we&#x27;ll do about N of them; it&#x27;s O(N^2).<p>The new algorithm, `concat (reverse xs)`, works because `xs` is just a list which can be reversed by traversing down it in O(N) time, then those can be merged together in O(N * m) time.
zvrbaover 11 years ago
So the original line of code has apparently been present since the very first import by Sigbjørn Finne in <a href="https://github.com/nominolo/HTTP/blob/c4765e822eb92196fec95560f8f640018d18737f/Network/HTTP/Base.hs" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;nominolo&#x2F;HTTP&#x2F;blob&#x2F;c4765e822eb92196fec955...</a> (check line 443).<p>If a Haskell expert (e.g., he authored hdirect -- an IDL compiler and interface with Win32 COM -- sadly defunct now) makes this kind of mistake, how are mere mortals supposed to reason about algorithmic efficiency?
评论 #6913745 未加载
评论 #6913607 未加载
评论 #6914342 未加载
评论 #6915921 未加载
评论 #6915260 未加载
评论 #6913613 未加载
评论 #6914540 未加载
评论 #6919436 未加载
jberrymanover 11 years ago
Here is the context<p><a href="http://www.reddit.com/r/haskell/comments/1sh67u/the_reason_why_cabal_update_takes_so_long/" rel="nofollow">http:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;haskell&#x2F;comments&#x2F;1sh67u&#x2F;the_reason_w...</a>
djuliusover 11 years ago
I guess nobody ever got upvoted for using StringBuffer&#x2F;StringBuilder instead of String concatenation in Java.
评论 #6915930 未加载
thinkpad20over 11 years ago
I&#x27;d definitely like to see an explanation of what&#x27;s going on, both at a high level and the specifics of the code. As a Haskell beginner-intermediate, I don&#x27;t really know what most of those functions are doing (much less the context of what that function&#x27;s purpose is), but I feel I could probably understand an explanation if it were given.
评论 #6912764 未加载
tibbonover 11 years ago
My Haskell skills still are growing. Can someone explain?
评论 #6912610 未加载
评论 #6912725 未加载
seliopouover 11 years ago
I for one prefer the more &quot;algebraic&quot; implementation. Why worry about performance when you get theorems for free?!<p>Monads.
评论 #6912791 未加载
评论 #6912624 未加载
评论 #6912569 未加载
评论 #6912598 未加载
anonymouscowar1over 11 years ago
Do people try and optimize Haskell programs? This is a part of Haskell that terrifies me.
评论 #6912871 未加载
评论 #6912724 未加载
评论 #6912884 未加载
评论 #6912729 未加载
评论 #6912658 未加载
thomasahleover 11 years ago
Doesn&#x27;t hlint catch stuff like this?
评论 #6915380 未加载
taybinover 11 years ago
Yep, this can also bite you in Erlang.