more GC optimizations
							parent
							
								
									a08a39c353
								
							
						
					
					
						commit
						6b257a9661
					
				|  | @ -280,7 +280,7 @@ namespace MoonTools.Core.Graph | |||
| 
 | ||||
|                         s.Remove(neighbor); | ||||
|                         t.Add(neighbor); | ||||
|                         if (s.Count == 0) { lexicographicSets.Remove(s); replacedSets.Remove(s); } | ||||
|                         if (s.Count == 0) { lexicographicSets.Remove(s); replacedSets.Remove(s); s.Dispose(); } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | @ -298,20 +298,20 @@ namespace MoonTools.Core.Graph | |||
|         { | ||||
|             return PostorderNodeDFS().Reverse(); | ||||
|         } | ||||
| 
 | ||||
|         readonly Dictionary<TNode, uint> preorder = new Dictionary<TNode, uint>(); | ||||
|         readonly Dictionary<TNode, uint> lowlink = new Dictionary<TNode, uint>(); | ||||
|         readonly Dictionary<TNode, bool> sccFound = new Dictionary<TNode, bool>(); | ||||
|         readonly Stack<TNode> sccQueue = new Stack<TNode>(); | ||||
|         readonly List<List<TNode>> sccResult = new List<List<TNode>>(); | ||||
|         List<PooledList<TNode>> sccs = new List<PooledList<TNode>>(); | ||||
| 
 | ||||
|         public IEnumerable<IEnumerable<TNode>> StronglyConnectedComponents() | ||||
|         { | ||||
|             preorder.Clear(); | ||||
|             lowlink.Clear(); | ||||
|             sccFound.Clear(); | ||||
|             sccQueue.Clear(); | ||||
|             sccResult.Clear(); | ||||
|             foreach (var scc in sccs) | ||||
|             { | ||||
|                 scc.Dispose(); | ||||
|             } | ||||
|             sccs.Clear(); | ||||
| 
 | ||||
|             var preorder = new PooledDictionary<TNode, uint>(); | ||||
|             var lowlink = new PooledDictionary<TNode, uint>(); | ||||
|             var sccFound = new PooledDictionary<TNode, bool>(); | ||||
|             var sccQueue = new PooledStack<TNode>(); | ||||
| 
 | ||||
|             uint preorderCounter = 0; | ||||
| 
 | ||||
|  | @ -364,7 +364,7 @@ namespace MoonTools.Core.Graph | |||
|                             if (lowlink[v] == preorder[v]) | ||||
|                             { | ||||
|                                 sccFound[v] = true; | ||||
|                                 var scc = new List<TNode> | ||||
|                                 var scc = new PooledList<TNode> | ||||
|                                 { | ||||
|                                     v | ||||
|                                 }; | ||||
|  | @ -374,7 +374,9 @@ namespace MoonTools.Core.Graph | |||
|                                     sccFound[k] = true; | ||||
|                                     scc.Add(k); | ||||
|                                 } | ||||
|                                 sccResult.Add(scc); | ||||
| 
 | ||||
|                                 sccs.Add(scc); | ||||
|                                 yield return scc; | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|  | @ -384,8 +386,6 @@ namespace MoonTools.Core.Graph | |||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return sccResult; | ||||
|         } | ||||
| 
 | ||||
|         public IEnumerable<IEnumerable<TNode>> SimpleCycles() | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Collections.Pooled; | ||||
| using MoreLinq; | ||||
| 
 | ||||
| namespace MoonTools.Core.Graph | ||||
|  | @ -12,13 +13,6 @@ namespace MoonTools.Core.Graph | |||
|         protected Dictionary<(TNode, TNode), TEdgeData> edgeToEdgeData = new Dictionary<(TNode, TNode), TEdgeData>(); | ||||
|         protected Dictionary<(TNode, TNode), int> weights = new Dictionary<(TNode, TNode), int>(); | ||||
| 
 | ||||
|         // store search sets to prevent GC | ||||
|         protected HashSet<TNode> openSet = new HashSet<TNode>(); | ||||
|         protected HashSet<TNode> closedSet = new HashSet<TNode>(); | ||||
|         protected Dictionary<TNode, int> gScore = new Dictionary<TNode, int>(); | ||||
|         protected Dictionary<TNode, int> fScore = new Dictionary<TNode, int>(); | ||||
|         protected Dictionary<TNode, TNode> cameFrom = new Dictionary<TNode, TNode>(); | ||||
| 
 | ||||
|         public IEnumerable<TNode> Nodes => nodes; | ||||
| 
 | ||||
|         public void AddNode(TNode node) | ||||
|  | @ -107,7 +101,7 @@ namespace MoonTools.Core.Graph | |||
|             return edgeToEdgeData[(v, u)]; | ||||
|         } | ||||
| 
 | ||||
|         private IEnumerable<(TNode, TNode)> ReconstructPath(Dictionary<TNode, TNode> cameFrom, TNode currentNode) | ||||
|         private IEnumerable<(TNode, TNode)> ReconstructPath(PooledDictionary<TNode, TNode> cameFrom, TNode currentNode) | ||||
|         { | ||||
|             while (cameFrom.ContainsKey(currentNode)) | ||||
|             { | ||||
|  | @ -121,11 +115,11 @@ namespace MoonTools.Core.Graph | |||
|         { | ||||
|             CheckNodes(start, end); | ||||
| 
 | ||||
|             openSet.Clear(); | ||||
|             closedSet.Clear(); | ||||
|             gScore.Clear(); | ||||
|             fScore.Clear(); | ||||
|             cameFrom.Clear(); | ||||
|             var openSet = new PooledSet<TNode>(ClearMode.Always); | ||||
|             var closedSet = new PooledSet<TNode>(ClearMode.Always); | ||||
|             var gScore = new PooledDictionary<TNode, int>(ClearMode.Always); | ||||
|             var fScore = new PooledDictionary<TNode, int>(ClearMode.Always); | ||||
|             var cameFrom = new PooledDictionary<TNode, TNode>(ClearMode.Always); | ||||
| 
 | ||||
|             openSet.Add(start); | ||||
| 
 | ||||
|  | @ -138,7 +132,19 @@ namespace MoonTools.Core.Graph | |||
| 
 | ||||
|                 if (currentNode.Equals(end)) | ||||
|                 { | ||||
|                     return ReconstructPath(cameFrom, currentNode).Reverse(); | ||||
|                     openSet.Dispose(); | ||||
|                     closedSet.Dispose(); | ||||
|                     gScore.Dispose(); | ||||
|                     fScore.Dispose(); | ||||
| 
 | ||||
|                     foreach (var edge in ReconstructPath(cameFrom, currentNode).Reverse()) | ||||
|                     { | ||||
|                         yield return edge; | ||||
|                     } | ||||
| 
 | ||||
|                     cameFrom.Dispose(); | ||||
| 
 | ||||
|                     yield break; | ||||
|                 } | ||||
| 
 | ||||
|                 openSet.Remove(currentNode); | ||||
|  | @ -163,7 +169,13 @@ namespace MoonTools.Core.Graph | |||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return Enumerable.Empty<(TNode, TNode)>(); | ||||
|             openSet.Dispose(); | ||||
|             closedSet.Dispose(); | ||||
|             gScore.Dispose(); | ||||
|             fScore.Dispose(); | ||||
|             cameFrom.Dispose(); | ||||
| 
 | ||||
|             yield break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,6 +1,7 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Collections.Pooled; | ||||
| using MoreLinq; | ||||
| 
 | ||||
| namespace MoonTools.Core.Graph | ||||
|  | @ -120,7 +121,7 @@ namespace MoonTools.Core.Graph | |||
|             return edgeToEdgeData[id]; | ||||
|         } | ||||
| 
 | ||||
|         private IEnumerable<Guid> ReconstructPath(Dictionary<TNode, Guid> cameFrom, TNode currentNode) | ||||
|         private IEnumerable<Guid> ReconstructPath(PooledDictionary<TNode, Guid> cameFrom, TNode currentNode) | ||||
|         { | ||||
|             while (cameFrom.ContainsKey(currentNode)) | ||||
|             { | ||||
|  | @ -135,11 +136,11 @@ namespace MoonTools.Core.Graph | |||
|         { | ||||
|             CheckNodes(start, end); | ||||
| 
 | ||||
|             openSet.Clear(); | ||||
|             closedSet.Clear(); | ||||
|             gScore.Clear(); | ||||
|             fScore.Clear(); | ||||
|             cameFrom.Clear(); | ||||
|             var openSet = new PooledSet<TNode>(ClearMode.Always); | ||||
|             var closedSet = new PooledSet<TNode>(ClearMode.Always); | ||||
|             var gScore = new PooledDictionary<TNode, int>(ClearMode.Always); | ||||
|             var fScore = new PooledDictionary<TNode, int>(ClearMode.Always); | ||||
|             var cameFrom = new PooledDictionary<TNode, Guid>(ClearMode.Always); | ||||
| 
 | ||||
|             openSet.Add(start); | ||||
| 
 | ||||
|  | @ -152,7 +153,19 @@ namespace MoonTools.Core.Graph | |||
| 
 | ||||
|                 if (currentNode.Equals(end)) | ||||
|                 { | ||||
|                     return ReconstructPath(cameFrom, currentNode).Reverse(); | ||||
|                     openSet.Dispose(); | ||||
|                     closedSet.Dispose(); | ||||
|                     gScore.Dispose(); | ||||
|                     fScore.Dispose(); | ||||
| 
 | ||||
|                     foreach (var edgeID in ReconstructPath(cameFrom, currentNode).Reverse()) | ||||
|                     { | ||||
|                         yield return edgeID; | ||||
|                     } | ||||
| 
 | ||||
|                     cameFrom.Dispose(); | ||||
| 
 | ||||
|                     yield break; | ||||
|                 } | ||||
| 
 | ||||
|                 openSet.Remove(currentNode); | ||||
|  | @ -178,7 +191,13 @@ namespace MoonTools.Core.Graph | |||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return Enumerable.Empty<Guid>(); | ||||
|             openSet.Dispose(); | ||||
|             closedSet.Dispose(); | ||||
|             gScore.Dispose(); | ||||
|             fScore.Dispose(); | ||||
|             cameFrom.Dispose(); | ||||
| 
 | ||||
|             yield break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -218,7 +218,8 @@ namespace Tests | |||
|                 .And | ||||
|                 .HaveCount(3); | ||||
| 
 | ||||
|             myGraph.Invoking(x => x.AStarShortestPath('a', 'z', (x, y) => 15)).Should().Throw<System.ArgumentException>(); | ||||
|             // have to call Count() because otherwise the lazy evaluation wont trigger | ||||
|             myGraph.Invoking(x => x.AStarShortestPath('a', 'z', (x, y) => 1).Count()).Should().Throw<System.ArgumentException>(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -248,7 +248,8 @@ namespace Tests | |||
|                 .And | ||||
|                 .HaveCount(3); | ||||
| 
 | ||||
|             myGraph.Invoking(x => x.AStarShortestPath('a', 'z', (x, y) => 15)).Should().Throw<System.ArgumentException>(); | ||||
|             // have to call Count() because otherwise the lazy evaluation wont trigger | ||||
|             myGraph.Invoking(x => x.AStarShortestPath('a', 'z', (x, y) => 1).Count()).Should().Throw<System.ArgumentException>(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue