本文介绍了为什么这是列表与LT;> .IndexOf代码,所以比列表[i]和手动比较快很多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对这段代码运行AQTime,我发现.IndexOf花费的时间与接近80%,而另一片的16%......它们似乎使用相同的ISEQUAL和其他程序。所谓的116000次插入30,000个项目。列表<的无;>对象获得超过200个元素。 (我可能会错误地使用AQTime,我期待这个)

 类PointD:IEquatable< PointD> 
{
公共双X,Y,Z;

布尔IEquatable< PointD> .Equals(PointD等)
{
回报率((X == other.X)及和放大器;(Y == other.Y) &放大器;&放大器(Z == other.Z));
}
}

类PerfTest
{
只读表< PointD> _pCoord3Points =新的List< PointD>();
公众诠释NewPoints;
公众诠释TotalPoints;

公共PerfTest()
{
NewPoints = 0;
TotalPoints = 0;
}
公众诠释CheckPointIndexOf(PointD PT)
{
INT retIndex = _pCoord3Points.IndexOf(PT);
如果(retIndex℃,)
{
_pCoord3Points.Add(PT);
NewPoints ++;
}
TotalPoints ++;
返回retIndex;
}

公众诠释CheckPointForBreak(PointD PT)
{
INT retIndex = -1;
的for(int i = 0; I< _pCoord3Points.Count;我++)
{
PointD otherPt = _pCoord3Points [I]
如果((pt.X == otherPt.X)及&放大器;
(pt.Y == otherPt.Y)及&放大器;
(pt.Z == otherPt。 Z))
{
retIndex = I;
中断;
}
}
如果(retIndex == -1)
{
NewPoints ++;
_pCoord3Points.Add(PT);
}
TotalPoints ++;
返回retIndex;
}

静态无效的主要()
{
const int的XMAX = 300;
const int的YMAX = 10;
const int的ZMAX = 10;
const int的IMAX = 4;

变种测试=新PerfTest();
//test.Init();
秒表SW = Stopwatch.StartNew();
的for(int i = 0; I< IMAX,我++)
{
的for(int x = 0; X< XMAX; X ++)
{
对于(INT Y = 0; Y< YMAX; Y ++)
{
为(INT Z = 0; z,其中,ZMAX; Z ++)
{
变种PT =新PointD {X = X,Y = Y,Z = Z};
test.CheckPointIndexOf(PT);
}
}
}

}
sw.Stop();
字符串输出=的String.Format(总计:{0:0}新:{1:0}的IndexOf:test.TotalPoints,test.NewPoints);
Console.Write(输出);
Console.WriteLine(sw.Elapsed);

测试=新PerfTest();
SW = Stopwatch.StartNew();
的for(int i = 0; I< IMAX,我++)
{
的for(int x = 0; X< XMAX; X ++)
{
对于(INT Y = 0; Y< YMAX; Y ++)
{
为(INT Z = 0; z,其中,ZMAX; Z ++)
{
变种PT =新PointD {X = X,Y = Y,Z = Z};
test.CheckPointForBreak(PT);
}
}
}

}
sw.Stop();
班产量的String.Format(总计:{0:0}新:{1:0} PointD [],test.TotalPoints,test.NewPoints);
Console.Write(输出);
Console.WriteLine(sw.Elapsed);
到Console.ReadLine();
}
}


解决方案

我做了如下假设:




  • PointD 是一个结构

  • 的IndexOf 确实比手动迭代名单慢



您可以加快的IndexOf 通过执行 IEquatable< T> 接口:

 结构PointD:IEquatable< PointD> 
{
公众诠释X;
公众诠释Ÿ;
公众诠释Z者除外;

公共布尔等于(PointD等)
{
回报率(this.X == other.X)及和放大器;
(this.Y == other.Y)及&放大器;
(this.Z == other.Z);
}
}



但没有实施 IEquatable< T> 接口,的IndexOf 将通过比较两个 PointD 元素 ValueType.Equals(对象等)这涉及昂贵的装箱操作



IEquatable 1所述的文件; T> 接口状态:



Here is my complete benchmark code:

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);
    }
}

On Windows 7, x64, .NET 4.0 x64 build I get the following timings (approx):

IndexOf:  00:00:04.8096623
For Loop: 00:00:00.0014203

When turning PointD into a class the timings change to

IndexOf:  00:00:01.0703627
For Loop: 00:00:00.0014190

When using a struct PointD implementing IEquatable<PointD> I get more "similar" results, but IndexOf is still slower (there is no significant difference when using a class now):

IndexOf:  00:00:00.3904615
For Loop: 00:00:00.0015218

这篇关于为什么这是列表与LT;&GT; .IndexOf代码,所以比列表[i]和手动比较快很多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 02:50