使用和不使用 LINQ 的线性搜索之间的区别

Posted

技术标签:

【中文标题】使用和不使用 LINQ 的线性搜索之间的区别【英文标题】:Difference between linear search with and without LINQ 【发布时间】:2017-11-19 18:53:26 【问题描述】:

使用比较变量的常规搜索算法与使用 lambda 运算符的搜索算法有什么区别?

他们在内部做了哪些不同的事情?您如何尽可能简单地描述它?两个版本都向用户提供相同的输出。

//LINQ: 
Console.WriteLine("Search for a word: ");
string userInput = Console.ReadLine();
var entries = logbook.Where(entry => entry.Any(item =>item.IndexOf(userInput, StringComparison.OrdinalIgnoreCase) > -1));
foreach (var entry in entries)
   
    Console.WriteLine(string.Join(", ", entry));    

break;

//Regular foreach: 
Console.WriteLine("Search for a word: ");

string userInput = Console.ReadLine();
foreach (string[] logs in logbook)

    if (logs[0] == userInput)
        Console.WriteLine("Word found!\n\nTitle: " + logs[0] + "\nText: " + logs[1] + "\n");
    else if (logs[1] == userInput)
        Console.WriteLine("Word found!\n\nTitle: " + logs[0] + "\nText: " + logs[1]);

【问题讨论】:

如果您能给我们类似的代码,这将非常有帮助 - 例如,您的第二段代码根本不使用 keyword,而第一段代码要求使用 @987654323 @ 但随后会忽略它,这表明您可能意味着使用userInput 而不是keyword... 但这不是您实际测试过的代码。同样,您的第二段代码与第一段代码执行完全不同的比较。 (如果您编辑问题以使代码片段更具可比性,请注意格式 - 我重新格式化了它以使其更具可读性,如果您进行编辑,请也这样做。) 您的问题没有真正定义好....有什么区别?..如果嵌套数组中不是 2 个字符串,而是有 100 个字符串怎么办?那么第二个版本不太可能是您正在寻找的。输出也不同..所以基本上你想比较哪两种情况?并比较哪些参数?性能/内存/可读性/可扩展性... @GiladGreen 对不起,我的问题更广泛,因为这两个只是作为一个例子。当我使用代码时,我可以在列表内的数组内的字符串上进行搜索。我只是好奇在这种情况下,lambda 与常规的有何不同。 你仍然让代码做完全不同的事情。当他们在这么多情况下给出不同的结果时,问哪个版本更清晰是没有意义的。 【参考方案1】:

我希望你已经准备好阅读一些代码。我已经更改了您的代码,因此它具有可比性。

foreach 版本

这是使用foreach的代码版本:

public static void Main()

    Console.WriteLine("Using foreach");
    string userInput = "1";
    var logbook = new List<string[]>  new string[]  "1", "2"  ;
    foreach (string[] logs in logbook)
    
        if (logs[0] == userInput)
            Console.WriteLine("Word found!\n\nTitle: " + logs[0] + "\nText: " + logs[1] + "\n");
        else if (logs[1] == userInput)
            Console.WriteLine("Word found!\n\nTitle: " + logs[0] + "\nText: " + logs[1]);
    

以下是编译器为上述代码生成的内容:

public static void Main()

    Console.WriteLine("Using foreach");
    string b = "1";
    List<string[]> list = new List<string[]>();
    List<string[]> arg_2F_0 = list;
    string[] expr_1F = new string[2];
    expr_1F[0] = "1";
    string[] expr_27 = expr_1F;
    expr_27[1] = "2";
    arg_2F_0.Add(expr_27);
    List<string[]> list2 = list;
    List<string[]>.Enumerator enumerator = list2.GetEnumerator();
    try
    
        while (enumerator.MoveNext())
        
            string[] current = enumerator.Current;
            bool flag = current[0] == b;
            if (flag)
            
                string[] expr_64 = new string[5];
                expr_64[0] = "Word found!\n\nTitle: ";
                string[] expr_6C = expr_64;
                expr_6C[1] = current[0];
                string[] expr_73 = expr_6C;
                expr_73[2] = "\nText: ";
                string[] expr_7B = expr_73;
                expr_7B[3] = current[1];
                string[] expr_82 = expr_7B;
                expr_82[4] = "\n";
                Console.WriteLine(string.Concat(expr_82));
            
            else
            
                bool flag2 = current[1] == b;
                if (flag2)
                
                    Console.WriteLine("Word found!\n\nTitle: " + current[0] + "\nText: " + current[1]);
                
            
        
    
    finally
    
        ((IDisposable)enumerator).Dispose();
    

Lambda 版本

这是使用 lambda 的代码版本:

public static void Main()

    Console.WriteLine("Using lambda");
    string userInput = "1";
    var logbook = new List<string[]>  new string[]  "1", "2"  ;
    var entries = logbook.Where(entry => entry.Any(item => item.IndexOf(userInput, StringComparison.OrdinalIgnoreCase) > -1));
    foreach (var entry in entries)
    
        Console.WriteLine(string.Join(", ", entry));
    

这是编译器为上述代码生成的内容。请注意下面代码中带有CompilerGenerated属性的私有类:

[CompilerGenerated]
private sealed class <>c__DisplayClass0_0

    public string userInput;

    public Func<string, bool> <>9__1;

    internal bool <Main>b__0(string[] entry)
    
        IEnumerable<string> arg_20_0 = entry;
        Func<string, bool> arg_20_1;
        if ((arg_20_1 = this.<>9__1) == null)
        
            arg_20_1 = (this.<>9__1 = new Func<string, bool>(this.<Main>b__1));
        
        return arg_20_0.Any(arg_20_1);
    

    internal bool <Main>b__1(string item)
    
        return item.IndexOf(this.userInput, StringComparison.OrdinalIgnoreCase) > -1;
    


public static void Main()

    Program.<>c__DisplayClass0_0 <>c__DisplayClass0_ = new Program.<>c__DisplayClass0_0();
    Console.WriteLine("Using lambda");
    <>c__DisplayClass0_.userInput = "1";
    List<string[]> list = new List<string[]>();
    List<string[]> arg_3A_0 = list;
    string[] expr_2A = new string[2];
    expr_2A[0] = "1";
    string[] expr_32 = expr_2A;
    expr_32[1] = "2";
    arg_3A_0.Add(expr_32);
    List<string[]> source = list;
    IEnumerable<string[]> enumerable = source.Where(new Func<string[], bool>(<>c__DisplayClass0_.<Main>b__0));
    IEnumerator<string[]> enumerator = enumerable.GetEnumerator();
    try
    
        while (enumerator.MoveNext())
        
            string[] current = enumerator.Current;
            Console.WriteLine(string.Join(", ", current));
        
    
    finally
    
        if (enumerator != null)
        
            enumerator.Dispose();
        
    

如果您注意Main 方法中的代码,它会利用编译器生成的类来完成它的工作。

我使用SharLab来完成上述工作。

【讨论】:

以上是关于使用和不使用 LINQ 的线性搜索之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

线性搜索和二分搜索有啥区别?

一元线性回归模型和一元线性回归方程之间的区别

O(1) 和 O(n) 之间的线性搜索差异

线性和二进制搜索

广义线性建模和常规逻辑回归之间的区别

线性基