Share via

Enhance the way of linear search

Jonathan 85 Reputation points
2026-05-31T04:50:50.82+00:00

Hi,

To C# linear search below

User's image

any advice to apply the following way on the above?

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.


4 answers

Sort by: Most helpful
  1. Nancy Vo (WICLOUD CORPORATION) 4,845 Reputation points Microsoft External Staff Moderator
    2026-06-01T07:02:34.11+00:00

    Hello @Jonathan ,

    Thanks for your question.

    Instead of applying SearchValues + Parallel.ForEach to your existing List, I would suggest a simpler and more effective approach - replace List<string> with HashSet<string>.

    You can refer to my example code:

    var ipSet = new HashSet<string>(
        File.Exists(@"c:/cmp/list11.txt")
            ? File.ReadLines(@"c:/cmp/list11.txt").Select(l => l.Trim())
            : Enumerable.Empty<string>(),
        StringComparer.OrdinalIgnoreCase
    );
    
    public static bool AddIfNotExists(string ip, HashSet<string> ipSet)
    {
        ip = ip.Trim();
    
        if (ipSet.Add(ip))
        {
            File.AppendAllText(@"c:/cmp/list11.txt", ip + Environment.NewLine);
            return true;
        }
    
        return false;
    }
    

    I hope this addresses your question. If this response was helpful, please consider following the guidance to provide feedback.

    Was this answer helpful?


  2. Bruce (SqlWork.com) 84,071 Reputation points
    2026-05-31T16:06:47.36+00:00

    The file I/O is orders of magnitude slower than the index lookup, you will never notice the difference. If the lookup is in a loop, you want to extract the file access to outside the loop. That is build a new list, the write the list once. also you don’t show how lookups are done. Converting the list to a dictionary or hash requires iteration over the list, so if there is only one lookup, the conversion is more expensive. Also if the list is small, find index is not expensive, and may be quicker.

    Was this answer helpful?

    0 comments No comments

  3. Viorel 126.9K Reputation points
    2026-05-31T08:13:54.1666667+00:00

    The solution depends on other details. For example, if the list is loaded from file, then:

    string path = @"c:\cmp\list11.txt";
    
    ip = ip.Trim( );
    
    if( !File.Exists( path ) || !File.ReadLines( path ).Any( a => a == ip ) )
    {
        File.AppendAllText( path, ip + Environment.NewLine );
    
        return true;
    }
    

    Was this answer helpful?

    0 comments No comments

  4. AI answer

    2026-05-31T04:51:05.11+00:00

    List<T>.FindIndex performs a linear search (O(n)) on every lookup. For frequent lookups or large collections, replace the list-based search with a data structure that provides O(1) lookup.

    A typical enhancement is to use HashSet<string> or Dictionary<string, TValue> instead of repeatedly calling FindIndex on List<string>:

    // Build a HashSet once from the existing list
    var ipSet = new HashSet<string>(list0);  // case-sensitive; use custom comparer if needed
    
    // When checking/adding a new IP
    if (!ipSet.Contains(ip))
    {
        ipSet.Add(ip);
    }
    
    // When persisting back to file, enumerate the set
    File.Delete(@"c:/cmp/list11.txt");
    
    using (var sw = new StreamWriter(@"c:/cmp/list11.txt", append: false))
    {
        foreach (var item in ipSet)
        {
            sw.WriteLine(item.Trim());
        }
    }
    

    Key improvements compared to the original linear search with FindIndex:

    1. HashSet<string>.Contains is O(1) on average, instead of O(n) for List<T>.FindIndex.
    2. The output file is opened once and written in a single pass, instead of opening a new StreamWriter inside the loop.
    3. The collection (ipSet) naturally enforces uniqueness, so duplicates are avoided without extra checks.

    If the order of elements must be preserved, maintain both a List<string> for ordering and a HashSet<string> for fast membership checks:

    var ipList = new List<string>();
    var ipSet  = new HashSet<string>();
    
    void AddIp(string ip)
    {
        if (ipSet.Add(ip))
        {
            ipList.Add(ip); // only added when new
        }
    }
    

    This pattern keeps lookups efficient while preserving insertion order for file output.


    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.