How do I improve the following?List<int> list = new List<int> { 1,2,3,0,5,7,0,6,0,0 };list.Reverse();list = list.SkipWhile(l => l == 0).ToList();list.Reverse();The goal is to trim trailing zeroes.
Trim, LINQ style
c#
Reversing the list twice as well as creating a new List just to remove trailing zeros is very inefficient. Running the below vs the other answers in a loop 10 million times shows this performs about 5 times faster than the accepted answer, and about 3 times faster than list.Take(list.FindLastIndex(item => item != 0) + 1).ToList();:List<int> list = new List<int> { 1, 2, 3, 0, 5, 7, 0, 6, 0, 0 };for (int index = list.Count - 1; index >= 0 && list[index] == 0; index--){    list.RemoveAt(index);}Update (again)I've redone the measurements using varying inputs. Each answer's code is executed in a loop 10 million times. I've also moved the list creation out of the loop so it doesn't pollute what I'm trying to measure.1 = Reverse + SkipWhile2 = For loop + RemoveAt3 = Take + FindLastIndex4 = GetRange + FindLastIndex5 = For loop + FindLastIndex + RemoveRange Empty lists:2258 ms62 ms844 ms488 ms138 msList of 100 non-zeros:52334 ms490 ms34056 ms2170 ms665 msList of 100 non-zeros, 1 trailing zero:53420 ms1297 ms34268 ms2360 ms1981 msList of 100 non-zeros, 100 trailing zeros:67423 ms12483 ms41153 ms8112 ms6958 msList of 100 zeros:15711 ms10448 ms5404 ms5075 ms5474 msCode used for testing:class Program{    static List<int>[] lists;    static List<int> nonZeros = new List<int>(Enumerable.Range(1, 100));    static List<int> zeros = new List<int>(Enumerable.Repeat(0, 100));    const int max = 10000000;    static void Main(string[] args)    {        List<int> result = null;        RecreateLists();        var sw = Stopwatch.StartNew();        for (int i = 0; i < max; i++)        {            result = Enumerable.Reverse(lists[i]).SkipWhile(x => x == 0).Reverse().ToList();        }        sw.Stop();        Console.WriteLine( 1. {0} ms, sw.ElapsedMilliseconds);        RecreateLists();        sw.Restart();        for (int i = 0; i < max; i++)        {            for (int index = lists[i].Count - 1; index >= 0 && lists[i][index] == 0; index--)            {                lists[i].RemoveAt(index);            }        }        sw.Stop();        Console.WriteLine( 2. {0} ms, sw.ElapsedMilliseconds);        RecreateLists();        sw.Restart();        for (int i = 0; i < max; i++)        {            result = lists[i].Take(lists[i].FindLastIndex(item => item != 0) + 1).ToList();        }        sw.Stop();        Console.WriteLine( 3. {0} ms, sw.ElapsedMilliseconds);        RecreateLists();        sw.Restart();        for (int i = 0; i < max; i++)        {            result = lists[i].GetRange(0, lists[i].FindLastIndex(x => x != 0) + 1);        }        sw.Stop();        Console.WriteLine( 4. {0} ms, sw.ElapsedMilliseconds);        RecreateLists();        sw.Restart();        int toRemove;        for (int i = 0; i < max; i++)        {            toRemove = lists[i].FindLastIndex(item => item != 0) + 1;            lists[i].RemoveRange(toRemove, lists[i].Count - toRemove);        }        sw.Stop();        Console.WriteLine( 5. {0} ms, sw.ElapsedMilliseconds);        lists = null;        GC.Collect();        Console.WriteLine(\nComplete!);        Console.ReadLine();    }    static void RecreateLists()    {        lists = null;        GC.Collect();        GC.WaitForPendingFinalizers();        lists = new List<int>[max];        var combined = new List<int>(nonZeros);        combined.AddRange(zeros);        for (int i = 0; i < max; i++)        {            lists[i] = new List<int>(combined);        }    }}