2

我需要在我的代码中使用System.Collections.Immutable ImmutableStack<T>但是我注意到自从使用它以来性能受到了一些影响。我想知道是否有替代方案可以提供更好的性能?

我测试Stack<T>ImmutableStack<T>以下内容

        static void Main(string[] args)
        {
            const int c_loopCount = 10000000;

            var watch = new Stopwatch();
            watch.Start();
            ImmutableStack<int> immStack = ImmutableStack<int>.Empty;
            for (int i = 0; i < c_loopCount; i++)
            {
                immStack = immStack.Push(i);
            }
            watch.Stop();
            TimeSpan ts = watch.Elapsed;

            string elapsedTime = $"{ts.Hours:00}:{ts.Minutes:00}:{ts.Seconds:00}.{ts.Milliseconds / 10:00}";
            Console.WriteLine($"ImmutableStack<T> RunTime {elapsedTime}");

            var watch2 = new Stopwatch();
            watch2.Start();
            var normalStack = new Stack<int>();
            for (int i = 0; i < c_loopCount; i++)
            {
                normalStack.Push(i);
            }
            TimeSpan ts2 = watch2.Elapsed;

            string elapsedTime2 = $"{ts2.Hours:00}:{ts2.Minutes:00}:{ts2.Seconds:00}.{ts2.Milliseconds / 10:00}";
            Console.WriteLine($"Stack<T> RunTime {elapsedTime2}");


            Console.ReadLine();
        }

平均Stack<T>比 . 快约 20%-25% ImmutableStack<T>。我在整个应用程序中都使用它,因此性能损失会造成损失。它需要是一个堆栈并且它需要是不可变的。关于可以采取哪些措施来提高这种性能,有什么建议吗?

4

1 回答 1

1

不变性是有代价的:immStack = immStack.Push(i);制作堆栈的副本,​​这比简单地将单个项目添加到可变堆栈需要更长的时间。此外,堆栈的每个先前副本都会变成垃圾,留下需要收集的 1000 万个对象。

完全不变性非常昂贵。您可以通过为堆栈设计自己的不可变接口并提供可变实现来使用虚假不变性。需要修改堆栈的代码直接写入堆栈,而应该看到不可变堆栈的代码将程序写入其不可变接口。

于 2017-06-22T01:28:55.820 回答