我在这段代码上运行AQTime,我发现.IndexOf占用了16%的时间,而另一段接近80%的时间...它们似乎使用相同的IsEqual和其他例程。被称为116,000次,插入30,000个项目。 List 对象没有一个超过200个元素。 (我可能未正确使用AQTime,正在调查此问题)class PointD : IEquatable<PointD>{ public double X, Y, Z; bool IEquatable<PointD>.Equals(PointD other) { return ((X == other.X) && (Y == other.Y) && (Z == other.Z)); }}class PerfTest{ readonly List<PointD> _pCoord3Points = new List<PointD>(); public int NewPoints; public int TotalPoints; public PerfTest() { NewPoints = 0; TotalPoints = 0; } public int CheckPointIndexOf(PointD pt) { int retIndex = _pCoord3Points.IndexOf(pt); if (retIndex < 0) { _pCoord3Points.Add(pt); NewPoints++; } TotalPoints++; return retIndex; } public int CheckPointForBreak(PointD pt) { int retIndex = -1; for (int i = 0; i < _pCoord3Points.Count; i++) { PointD otherPt = _pCoord3Points[i]; if ((pt.X == otherPt.X) && (pt.Y == otherPt.Y) && (pt.Z == otherPt.Z)) { retIndex = i; break; } } if (retIndex == -1) { NewPoints++; _pCoord3Points.Add(pt); } TotalPoints++; return retIndex; } static void Main() { const int xmax = 300; const int ymax = 10; const int zmax = 10; const int imax = 4; var test = new PerfTest(); //test.Init(); Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < imax; i++) { for (int x = 0; x < xmax; x++) { for (int y = 0; y < ymax; y++) { for (int z = 0; z < zmax; z++) { var pt = new PointD { X = x, Y = y, Z = z }; test.CheckPointIndexOf(pt); } } } } sw.Stop(); string output = string.Format("Total: {0:0} New: {1:0} IndexOf: ", test.TotalPoints, test.NewPoints); Console.Write(output); Console.WriteLine(sw.Elapsed); test = new PerfTest(); sw = Stopwatch.StartNew(); for (int i = 0; i < imax; i++) { for (int x = 0; x < xmax; x++) { for (int y = 0; y < ymax; y++) { for (int z = 0; z < zmax; z++) { var pt = new PointD { X = x, Y = y, Z = z }; test.CheckPointForBreak(pt); } } } } sw.Stop(); output = string.Format("Total: {0:0} New: {1:0} PointD[] ", test.TotalPoints, test.NewPoints); Console.Write(output); Console.WriteLine(sw.Elapsed); Console.ReadLine(); }} (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 我做了以下假设: PointD是一个结构 IndexOf确实比手动迭代列表慢您可以通过实现IndexOf接口(interface)来加快IEquatable<T>的运行速度:struct PointD : IEquatable<PointD>{ public int X; public int Y; public int Z; public bool Equals(PointD other) { return (this.X == other.X) && (this.Y == other.Y) && (this.Z == other.Z); }}如果不实现IEquatable<T>接口(interface),IndexOf将使用PointD比较这两个ValueType.Equals(object other)元素,这涉及昂贵的装箱操作。IEquatable<T>接口(interface)的文档指出: The IEquatable<T> interface is used by generic collection objects such as Dictionary<TKey, TValue>, List<T>, and LinkedList<T> when testing for equality in such methods as Contains, IndexOf, LastIndexOf, and Remove. It should be implemented for any object that might be stored in a generic collection.这是我完整的基准代码:using System;using System.Collections.Generic;using System.Diagnostics;struct PointD{ public int X; public int Y; public int Z;}class PerfTest{ List<PointD> _pCoord3Points = new List<PointD>(); int checkPointIndexOf(PointD pt) { return _pCoord3Points.IndexOf(pt); } int checkPointForBreak(PointD pt) { int retIndex = -1; for (int i = 0; i < _pCoord3Points.Count; i++) { PointD otherPt = _pCoord3Points[i]; if ((pt.X == otherPt.X) && (pt.Y == otherPt.Y) && (pt.Z == otherPt.Z)) retIndex = i; break; } return retIndex; } void init() { for (int x = 0; x < 100; x++) { for (int y = 0; y < 10; y++) { for (int z = 0; z < 10; z++) { PointD pt = new PointD() { X = x, Y = y, Z = z }; _pCoord3Points.Add(pt); } } } } static void Main(string[] args) { PerfTest test = new PerfTest(); test.init(); Stopwatch sw = Stopwatch.StartNew(); for (int x = 0; x < 100; x++) { for (int y = 0; y < 10; y++) { for (int z = 0; z < 10; z++) { PointD pt = new PointD() { X = x, Y = y, Z = z }; test.checkPointIndexOf(pt); } } } sw.Stop(); Console.WriteLine(sw.Elapsed); sw = Stopwatch.StartNew(); for (int x = 0; x < 100; x++) { for (int y = 0; y < 10; y++) { for (int z = 0; z < 10; z++) { PointD pt = new PointD() { X = x, Y = y, Z = z }; test.checkPointForBreak(pt); } } } sw.Stop(); Console.WriteLine(sw.Elapsed); }}在Windows 7,x64,.NET 4.0 x64构建上,我得到以下计时(大约):索引:: 00:00:04.8096623对于循环:00:00:00.0014203将PointD转换为class时,计时更改为索引:00:00:01.0703627对于循环:00:00:00.0014190当使用实现struct PointD的IEquatable<PointD>时,我会得到更多的“相似”结果,但是IndexOf仍然较慢(现在使用class并没有明显的区别):索引:: 00:00:00.3904615对于循环:00:00:00.0015218 (adsbygoogle = window.adsbygoogle || []).push({});
09-26 11:39