-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replacing Algebra.Graph by Maybe (Algebra.Graph.NonEmpty) #90
Comments
@nobrakal Many thanks for the experiment! I have been wondering recently: do we even need graphs that can be empty? Presumably, non-empty graphs cover 99% of use-cases and are generally safer not only in terms of internal representation, but for the users too.
I don't understand this: it's just a single comparison, right? It shouldn't even be measurable. |
With the actual
But I think we definitely need to focus more in
I don't understand yet too... It is a huge drop for a single comparison ! |
Perhaps, it prevents some important optimisation? Could you investigate by looking at generated Core? |
It was the case for I fixed it by hand by writing: edges :: [(a, a)] -> Graph a
edges [] = Empty
edges (x:xs) = G $ Just $ foldr (N.Overlay . uncurry N.edge) (uncurry N.edge x) xs It dropped to ratio to |
@nobrakal Why not use |
In fact I need to do the change in edges1 (x :| xs) = foldr (Overlay . uncurry edge) (uncurry edge x) xs The problem is that the combination of |
The last benchs:
So everything is ok, note that the rough number for |
Hmm, this makes me think that the benchmarking suite is too fragile: it shouldn't measure performance by looking up only a single vertex. It should average time for several different vertices, otherwise some libraries/implementations will get an unfair advantage by chance. |
Sorry, I wasn't clear. I actually test 4/5 vertices (for a graph with n vertices I test the search of vertex 0, n/3, 2*n/3, n+1). It might worth it to add some vertices, but I don't think it will really change the results ^^ |
@nobrakal Ah, I see, thanks for clarifying... Yes, that's what one gets for having O(n) complexity :) There is really a huge swing between best and worst cases. |
Since we are now starting to look more carefully at non-empty graphs, I think it may be worth adding them into the regression suite... Perhaps, into a separate Travis instance, so we don't hit the time limit? |
Yeah indeed ^^.
I totally agree, I will send a PR |
I just realised that
Not sure this observartion is useful, but I thought I better record it here. I still think |
Hi,
I have been working on a different implementation of
Algebra.Graph
, based onAlgebra.Graph.NonEmpty
.The idea is to have:
Using patterns, with:
One can reproduce the traditional
Algebra.Graph
interface.This big change can be summarized with some functions:
We now check the neutrality of
empty
directly into theoverlay
andconnect
functions.edges
become more complicated and slower.foldg
is directly based onfoldg1
(and this is the case for others functions, when possible).fmap
allow a pretty syntax when a function will act as the identity on the empty graph.Some benefits
Overlay
orConnect
that the two graphs are both non-empty.Empty
constructor,foldg1
is faster thanfoldg
. Thus, inspection functions are faster.Some problems:
induce
because we have to wrap the intermediate results into theMaybe
monad.Benchs:
Using the pretty little script I made (on my own computer with graph with 1000 vertices):
So for example
addEdge
was so fast, that there is drop here when we pattern match to see if it the previous gaph was empty or not.(Note that I have sneaked the improvement on
hasEdge
of #88 (but it is even better here)).The benchmarked code is here: https://github.com/nobrakal/alga/blob/MaybeNonEmpty/src/Algebra/Graph.hs
The text was updated successfully, but these errors were encountered: