Here's my data for "100 random point.dwg" with Tolerance(1, 1) :
DistinctHashSet
Found 2 duplicate(s) in a 10000 items collection.
Elapsed milliseconds : 5150.0162
DistinctEnumerable
Found 2 duplicate(s) in a 10000 items collection.
Elapsed milliseconds : 3502.6673
Sure, setting the HashCode to 0 is cheating, as is the creation of a sequence where the Current property is never touched.
public class MyEqualityComparer : IEqualityComparer<Point3d>
{
Tolerance m_tol;
public MyEqualityComparer(Tolerance tol)
{
m_tol = tol;
}
public bool Equals(Point3d a, Point3d b)
{
return a.IsEqualTo(b, m_tol);
}
public int GetHashCode(Point3d pnt)
{
return 0;
}
}
public class Commands
{
[CommandMethod("DistinctEnumerable")]
public void DistinctEnumerable() { cmd("DistinctEnumerable"); }
[CommandMethod("DistinctHashSet")]
public void DistinctHashSet() { cmd("DistinctHashSet"); }
private void cmd(string what)
{
Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor;
PromptDoubleResult pdr = ed.GetDouble("Tolerance: ");
if (pdr.Status != PromptStatus.OK) return;
SelectionFilter sf = new SelectionFilter(new TypedValue[] { new TypedValue((int)DxfCode.Start, "POINT") });
PromptSelectionResult psr = ed.GetSelection(sf);
if (psr.Status != PromptStatus.OK) return;
int numin, numout;
long ticks;
dupPts(what, pdr.Value, psr.Value, out numin, out numout, out ticks);
ed.WriteMessage(
"\n{0} " +
"\nFound {1} duplicate(s) in a {2} items collection. " +
"\nElapsed milliseconds : {3} ",
what,
numin - numout,
numin,
(double)ticks / (double)TimeSpan.TicksPerMillisecond);
}
private void dupPts(string what, double eps, SelectionSet sset, out int numin, out int numout, out long ticks)
{
Database db = acApp.DocumentManager.MdiActiveDocument.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Point3dCollection pts = new Point3dCollection();
foreach (SelectedObject so in sset)
{
DBPoint dbp = (DBPoint)tr.GetObject(so.ObjectId, OpenMode.ForRead);
pts.Add(dbp.Position);
}
Tolerance tol = new Tolerance(eps, eps);
numin = pts.Count;
Stopwatch sw = Stopwatch.StartNew();
if (what == "DistinctEnumerable")
{
IEnumerable<Point3d> enumerable = pts.Cast<Point3d>().Distinct<Point3d>(new MyEqualityComparer(tol));
numout = enumerable.Count<Point3d>();
}
else if (what == "DistinctHashSet")
{
HashSet<Point3d> hash = new HashSet<Point3d>(pts.Cast<Point3d>(), new MyEqualityComparer(tol));
numout = hash.Count;
}
else numout = 0;
sw.Stop();
ticks = sw.Elapsed.Ticks;
tr.Commit();
}
}
}