C# 查看列表的最快方法<;T>;约会

C# 查看列表的最快方法<;T>;约会,c#,generics,.net-2.0,generic-list,C#,Generics,.net 2.0,Generic List,我有一个机器工作的日期列表,但不包括机器停机的日期。我需要创建一个工作日和未工作日的列表。我不知道最好的方法是什么。我从增加一个范围内的所有天数开始,并通过每次迭代整个列表来检查该日期是否在列表中。我正在寻找一种更有效的方法来查找日期 class machineday { datetime WorkingDay; } class machinedaycollection : List<machineday> { public List<TimeCatEvent> Ge

我有一个机器工作的日期列表,但不包括机器停机的日期。我需要创建一个工作日和未工作日的列表。我不知道最好的方法是什么。我从增加一个范围内的所有天数开始,并通过每次迭代整个列表来检查该日期是否在列表中。我正在寻找一种更有效的方法来查找日期

class machineday
{
 datetime WorkingDay;
}

class machinedaycollection : List<machineday>
{
public List<TimeCatEvent> GetAllByCat(string cat)
{
  _CategoryCode = cat;


  List<machineday> li = this.FindAll(delegate(machinedaydummy) { return true; });
  li.Sort(sortDate);
  return li;
}

int sortDate(machinedayevent1, machinedayevent2)
{
  int returnValue = -1;
  if (event2.date < event1.date)
  {
    returnValue = 0;
  }
  else if (event2.date == event1.date)
  {
    //descending
    returnValue = event1.date.CompareTo(event2.date);
  }
  return returnValue;
}
}
class-machineday
{
日期时间工作日;
}
类machinedaycollection:列表
{
公共列表GetAllByCat(字符串cat)
{
_类别代码=cat;
List li=this.FindAll(委托(machinedaydummy){return true;});
li.Sort(sortDate);
返回李;
}
内部排序日期(加工日期1,加工日期2)
{
int returnValue=-1;
如果(event2.date
建立一个有效日期列表,并使用LINQ的
可枚举方法从中减去机器日集合。除了扩展方法。大概是这样的:

IEnumerable<DateTime> dates = get_candidate_dates();
var holidays = dates.Except(machinedays.Select(m => m.WorkingDay));
IEnumerable dates=获取候选日期();
var假日=日期。除了(machinedays.Select(m=>m.WorkingDay));
get\u candidates()
方法甚至可以是一个迭代器,动态生成某个范围内的所有日期,而不是预先存储的所有日期列表


Enumerable的方法相当聪明,通常会在性能方面做得很好,但如果您想要最快的算法,这将取决于您计划如何使用结果。

对日期排序,并在增加计数器的同时迭代结果列表。每当计数器与当前列表元素不匹配时,您就会发现列表中缺少一个日期

List<DateTime> days = ...;
days.Sort();
DateTime dt = days[0].Date;
for (int i = 0; i < days.Length; dt = dt.AddDays(1))
{
    if (dt == days[i].Date)
    {
        Console.WriteLine("Worked: {0}", dt);
        i++;
    }
    else
    {
        Console.WriteLine("Not Worked: {0}", dt);
    }
}
列出天数=。。。;
天。排序();
DateTime dt=天[0]。日期;
对于(int i=0;i

(这假设列表中没有重复的日期。)

假设列表已排序且机器大部分时间都在“工作”,则可以通过按月分组日期并跳过其间的日期来避免重复所有日期。类似这样的东西(你需要清理):

int chunksize=60;//根据数据进行调整
machineday currentDay=MyMachineDay集合[0];
for(int i=0;i
对不起,伙计们,我不太喜欢你们的解决方案。 我认为你应该创建一个包含日期的哈希表。您可以在工作日内只进行一次交互

然后,使用

myHashTable.ContainsKey(day); // this is efficient
简单、优雅、快捷


我认为您的解决方案使用的是指数时间,这是线性或对数时间(这实际上是一件好事)。

我怀疑您是否希望列出工作和不工作的天数

您的问题标题表明您想知道系统是否在特定日期启动。计算%正常运行时间似乎也是合理的。这两种方法都不需要构建间隔中所有时间瞬间的列表

对服务时间进行排序。对于第一个问题,请执行二进制搜索以查找您关心的日期,并检查前面的条目是否是系统正在脱机维护或重新投入使用。对于%正常运行时间,按对计算(停止维护,恢复服务),使用减法计算维护持续时间,将这些时间相加。然后使用减法计算总间隔的长度


如果你的问题实际上并不意味着你在跟踪维护间隔(或等效的使用间隔),那么你可以忽略这个答案。

LINQ是这个问题的一个选项吗?也许不是(我刚刚注意到.Net 2标记),但是
Enumerable
可以从.Net 2.0访问,尽管语法比较笨拙。您只需要添加对System.Core程序集的引用。这不是一个好的解决方案,因为它需要15行代码才能完成一两行代码。看看Marcelo Cantos提供的基于集合的解决方案。尽管except方法在您的.net版本中可能不可用,但您可以自己以可重用的方式编写它。@usr:您看过标记了吗?这是在.NET 2.0中实际工作的唯一解决方案。恒定的时间和内存,但内存常量很大,这是一件非常糟糕的事情。@Ben:不一定,这取决于性能是否是更关键的问题。更好的性能往往是以牺牲一些其他资源为代价的,比如内存。有趣的是,我从来没有想过在这个方向上巨大?出于保守,使用大约1mb的内存,您可以存储45年的日期。在处理简单数据类型时,内存通常不再是一个问题。这与15年前不同,还记得那些日子吗????拥有640k的机器!!问题是为了平衡设置哈希数据结构所花费的时间,您必须进行多少次搜索。通过二进制搜索,仅列出状态在“服务中”和“维护中”之间变化的日期的排序密集结构将非常快。
myHashTable.ContainsKey(day); // this is efficient