C#LINQ性能当扩展方法调用where where子句时

时间:2018-04-12 08:11:39

标签: c# performance linq

我有像这样的LINQ查询

public static bool CheckIdExists(int searchId)
{
   return itemCollection.Any(item => item.Id.Equals(searchId.ConvertToString()));
}

item.Idstring,而searchIdint.ConvertToString()是一个将int转换为string

的扩展程序

ConvertToString的代码:

public static string ConvertToString(this object input)
{
   return Convert.ToString(input, CultureInfo.InvariantCulture);
}

现在我的查询是, searchId.ConvertToString()中的每个项目都会执行itemCollection吗?

事先计算searchId.ConvertToString()并调用下面的方法会改善效果吗?

public static bool CheckIdExists(int searchId)
{
   string sId=searchId.ConvertToString();
   return itemCollection.Any(item => item.Id.Equals(sId));
}

如何调试这两种情况并观察其表现?

4 个答案:

答案 0 :(得分:2)

我重新生成了你在问题中谈到的场景。我尝试了下面的代码并得到了这个输出。

但这是你可以调试它的方法。

static List<string> itemCollection = new List<string>();

static void Main(string[] args)
{

    for (int i = 0; i < 10000000; i++)
    {
        itemCollection.Add(i.ToString());
    }

    var watch = new Stopwatch();
    watch.Start();

    Console.WriteLine(CheckIdExists(580748));
    watch.Stop();
    Console.WriteLine($"Took {watch.ElapsedMilliseconds}");

    var watch1 = new Stopwatch();
    watch1.Start();

    Console.WriteLine(CheckIdExists1(580748));
    watch1.Stop();
    Console.WriteLine($"Took {watch1.ElapsedMilliseconds}");

    Console.ReadLine();
}

public static bool CheckIdExists(int searchId)
{
    return itemCollection.Any(item => item.Equals(ConvertToString(searchId)));
}

public static bool CheckIdExists1(int searchId)
{
    string sId =ConvertToString(searchId);

    return itemCollection.Any(item => item.Equals(sId));
}

public static string ConvertToString(int input)
{
    return Convert.ToString(input, CultureInfo.InvariantCulture);
}

<强>输出:

True
Took 170
True
Took 11

答案 1 :(得分:1)

最终指南需要多长时间。您可以创建秒表来记录任何代码的性能。只需使用ElapsedMilliseconds即可查看已执行的时间。对于非常短的操作,我建议使用非常长的循环来获得更准确的时间长度。

var watch = new Stopwatch();
watch.Start();
/// CODE HERE (IDEALLY IN A LONG LOOP)
Debub.WriteLine($"Took {watch.ElapsedMilliseconds}");

答案 2 :(得分:0)

是的,获取字符串一次应该更快。但是我想编译器会为你优化这个东西(我只是怀疑这个,不要做任何事情来支持它。我只记得编译器非常擅长检测那些没有改变的事情。)

不,它不是针对每个项目计算的,因为LINQ方法Any不一定检查所有项目。对于第一个匹配项,它返回true。检查所有项目的唯一方案是lambda返回true的情况。

如果您想测试速度差异,请确保拥有更多数据 - 否则差异可能太小。

只是做:

itemCollection = Enumerable.Range(0, 1000).SelectMany(x => itemCollection).ToList() // or array or whatever the type of collection you have

比使用StopWatch测量时间,就像@RobSedgwick所说

答案 3 :(得分:0)

我认为你有两个解决方案:

1-在日志datetime.now中创建日志和meke 2-您可以使用诊断工具选项卡

希望这有助于你