Using LINQ to remove elements from a List

前端 未结 14 2200
抹茶落季
抹茶落季 2020-11-22 11:09

Say that I have LINQ query such as:

var authors = from x in authorsList
              where x.firstname == \"Bob\"
              select x;

14条回答
  •  忘掉有多难
    2020-11-22 11:39

    I was wondering, if there is any difference between RemoveAll and Except and the pros of using HashSet, so I have done quick performance check :)

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    
    namespace ListRemoveTest
    {
        class Program
        {
            private static Random random = new Random( (int)DateTime.Now.Ticks );
    
            static void Main( string[] args )
            {
                Console.WriteLine( "Be patient, generating data..." );
    
                List list = new List();
                List toRemove = new List();
                for( int x=0; x < 1000000; x++ )
                {
                    string randString = RandomString( random.Next( 100 ) );
                    list.Add( randString );
                    if( random.Next( 1000 ) == 0 )
                        toRemove.Insert( 0, randString );
                }
    
                List l1 = new List( list );
                List l2 = new List( list );
                List l3 = new List( list );
                List l4 = new List( list );
    
                Console.WriteLine( "Be patient, testing..." );
    
                Stopwatch sw1 = Stopwatch.StartNew();
                l1.RemoveAll( toRemove.Contains );
                sw1.Stop();
    
                Stopwatch sw2 = Stopwatch.StartNew();
                l2.RemoveAll( new HashSet( toRemove ).Contains );
                sw2.Stop();
    
                Stopwatch sw3 = Stopwatch.StartNew();
                l3 = l3.Except( toRemove ).ToList();
                sw3.Stop();
    
                Stopwatch sw4 = Stopwatch.StartNew();
                l4 = l4.Except( new HashSet( toRemove ) ).ToList();
                sw3.Stop();
    
    
                Console.WriteLine( "L1.Len = {0}, Time taken: {1}ms", l1.Count, sw1.Elapsed.TotalMilliseconds );
                Console.WriteLine( "L2.Len = {0}, Time taken: {1}ms", l1.Count, sw2.Elapsed.TotalMilliseconds );
                Console.WriteLine( "L3.Len = {0}, Time taken: {1}ms", l1.Count, sw3.Elapsed.TotalMilliseconds );
                Console.WriteLine( "L4.Len = {0}, Time taken: {1}ms", l1.Count, sw3.Elapsed.TotalMilliseconds );
    
                Console.ReadKey();
            }
    
    
            private static string RandomString( int size )
            {
                StringBuilder builder = new StringBuilder();
                char ch;
                for( int i = 0; i < size; i++ )
                {
                    ch = Convert.ToChar( Convert.ToInt32( Math.Floor( 26 * random.NextDouble() + 65 ) ) );
                    builder.Append( ch );
                }
    
                return builder.ToString();
            }
        }
    }
    

    Results below:

    Be patient, generating data...
    Be patient, testing...
    L1.Len = 985263, Time taken: 13411.8648ms
    L2.Len = 985263, Time taken: 76.4042ms
    L3.Len = 985263, Time taken: 340.6933ms
    L4.Len = 985263, Time taken: 340.6933ms
    

    As we can see, best option in that case is to use RemoveAll(HashSet)

提交回复
热议问题