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