C# 如何加速这个算法?

C# 如何加速这个算法?,c#,.net,plinq,C#,.net,Plinq,这种计数方法在一个单元测试中相当慢。可以通过并行化来改进它吗 编辑:明确地说,我不能更改日历界面或实现。我对计数算法感兴趣 public static int CountBusinessDays(ICalendar calendar, DateTime start, DateTime end) { int nBusinessDays = 0; for (DateTime current = start; current <= end; current = current.

这种计数方法在一个单元测试中相当慢。可以通过并行化来改进它吗

编辑:明确地说,我不能更改日历界面或实现。我对计数算法感兴趣

public static int CountBusinessDays(ICalendar calendar, DateTime start, DateTime end)
{
    int nBusinessDays = 0;

    for (DateTime current = start; current <= end; current = current.AddDays(1))
    {
        if (calendar.IsBusinessDay(current))
            ++nBusinessDays;
    }

    return nBusinessDays;
}

public interface ICalendar
{
    bool IsBusinessDay(DateTime day);
}
public static int CountBusinessDays(ICalendar日历、日期时间开始、日期时间结束)
{
int N营业日=0;

对于(DateTime current=start;current如果您无法更改实现,那么唯一可能的加速方法就是通过并行化(无论您是否通过应用程序代码处理多个线程)


由于我们不知道calendar.IsBusinessDay()中发生了什么,我们无法告诉您是否会更快。可能您有隐式序列化,可能您资源匮乏,可能它只是因为线程不安全而中断。如果您不知道答案,我可以想出4个选项。1)尝试并行化,看看它是否有效,是否是影响因素。2)修改或删除测试用例,使其更快。3)投入更多/更快的硬件,4)适应它。

因此,首先,这里有一个简单的助手方法,从给定点开始生成无限的天数序列:

public static IEnumerable<DateTime> Days(DateTime start)
{
    while (true)
    {
        yield return start;
        start = start.AddDays(1);
    }
}
接下来,我们可以使用PLINQ对每天的计算进行并行化:

return allDays.AsParallel()
    .Where(day => calendar.IsBusinessDay(day))
    .Count();

请注意,计算给定日期是否为工作日可能并不特别耗时。如果是这种情况,则很可能管理所有不同线程的开销实际花费的时间比并行工作所获得的时间要多。基础集合的大小也很重要;如果时间越长,实现并行化的可能性就越大。您应该运行一些测试,通过添加/删除
AsParallel
调用,看看这是否真的是一场胜利。

您是否有权访问
ICalendar
实现?或者您是否可以更改接口,以便使用一种方法来提供业务数量ss days?我认为在
ICalendar
上下文中实现这一点会更简单,因为你应该有足够的信息来简单地计算它,而不进行迭代,这是我们无法回答的。你尝试过吗?从找出它为什么如此慢开始。
IsBusinessDay
是否可能调用数据库?并使操作瘫痪操作并衡量是否有帮助。IsBusinessDay的实现情况大致如何?如果它每天都进行web服务调用,那么通过批量下载工作日列表可以获得最大的速度提升。这一切都取决于
IsBusinessDay
的实现。其余的都很简单。但是如果使用数据库,使用它(
selectcount(*)…
)。谢谢,这将慢速单元测试从约450毫秒加速到约300毫秒
return allDays.AsParallel()
    .Where(day => calendar.IsBusinessDay(day))
    .Count();