-
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
NonEmpty graphs optimizations #94
Conversation
src/Algebra/Graph/NonEmpty.hs
Outdated
edges1 = overlays1 . fmap (uncurry edge) | ||
edges1 (x :| xs) = foldr (Overlay . edgeTuple) (edgeTuple x) xs | ||
where | ||
edgeTuple = uncurry edge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would drop edgeTuple
-- I don't think duplicating uncurry edge
is such a big deal.
hasEdge :: Eq a => a -> a -> NonEmptyGraph a -> Bool | ||
hasEdge = T.hasEdge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you now provide much faster implementations compared to the default ones in ToGraph
, you should use them in the instance ToGraph
declaration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Writing this improvement in the ToGraph
instance drop a the performances:
Alga is the improvement moved in the ToGraph instance, and AlgaOld is the current state of this PR.
Mesh
100 | |
---|---|
Alga | 6.383 μs |
AlgaOld | 5.100 μs |
Clique
100 | |
---|---|
Alga | 716.0 μs |
AlgaOld | 170.4 μs |
I am not sure why...
I think this is because I can't use NonEmpty
graphs in ToGraph
, so I can 't use Algebra.Graph.NonEmpty.Vertex
but only Algebra.Graph.Vertex
, and thus, in the final step, I can only use foldg
instead of foldg1
.
Also, because we are not sure that induce
is removing empty leaves, we loose the fast hasSelfLoop
(because it was defined in ToGraph
as hasSelfLoop x = hasEdge x x
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nobrakal I meant this:
instance ToGraph NonEmpty where
...
hasEdge = hasEdge -- use faster implementation instead of the default one
Surely this can't reduce the performace of hasEdge
itself!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But users of the typeclass might get the benefit.
So, the rule is: if you use the default implementation, i.e. x = T.x
then the instance declaration uses default methods. But otherwise you need to redefine default instance methods, i.e. add x = x
to the instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, it is done now :)
@nobrakal Thanks, I've added a couple of comments.
Amazing! For these cases we really should be saying |
src/Algebra/Graph/NonEmpty.hs
Outdated
|
||
-- | Like 'edgeList' but specialised for NonEmptyGraph with vertices of type 'Int'. | ||
edgeIntList :: NonEmptyGraph Int -> [(Int,Int)] | ||
edgeIntList = AIM.edgeList . foldg1 AIM.vertex AIM.overlay AIM.connect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presumably, foldg1 AM.vertex AM.overlay AM.connect
and foldg1 AIM.vertex AIM.overlay AIM.connect
will appear in the instance ToGraph
, so you could simply write toAdjacencyIntMap
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presumably, foldg1 AM.vertex AM.overlay AM.connect and foldg1 AIM.vertex AIM.overlay AIM.connect will appear in the instance ToGraph
You are right for edgeList
, it is a mistake.
For edgeIntList
there is only adjacencyIntMap
in ToGraph
, so I cannot use it for AM.edgeSet
since adjacencyIntMap
only return a IntMap IntSet
.
I can add toAdjacencyIntMap
in ToGraph
if you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, you are right, this seems to work only with edgeList
.
@snowleopard Ahaha, yes this is great :) Thanks for the comments, I will fix address them shortly. The travis build is failing here because I just added some missing algorithms to the bench suite, and now the suite take too much time to run. Since the added algorithms are based on their counterpart from AdjacencyMap, I will drop them. A PR is coming soon to fix that ! |
@nobrakal Thanks, merged! |
Hi,
As discussed in #93 , here are several optimizations to
Algebra.Graph.NonEmpty
.Mainly with:
SPECIALIZE
pragma when possible and usefulRULES
when possible and usefulThe benchmarks:
So everything is green, the drop of
hasVertex
as already been documented here: #90 (comment)