c# - 将旧版 .NET 集合迁移到其通用对应集合

标签 c# .net performance arraylist generic-collections

目前,我正在开发一个包含大量遗留代码的项目,其中包括使用非通用集合,例如 .NET 的 ArrayList , HashTable

我知道使用这些类型的集合作为原始类型在性能方面是一个糟糕的主意,如 mentioned by List's documentation在“性能考虑因素”部分中(我通过快速且简单的 LinqPad 查询再次确认了这一点 - 附在最后)。

乍一看,执行某种搜索/替换操作来替换这些旧集合似乎没有任何问题。但由于它会影响代码库的很大一部分,我担心 List<T> 会产生副作用。给出 ArrayList 时,其行为不符合“预期”应用程序已经依赖的特定行为。

以前有人大规模进行过这种类型的转换吗?如果是,是否存在 .NET 文档中未提及的微妙问题?


void Main()
{
    var size = 1000000;
    var array = new int[size];
    var list = new List<int>();
    var arrayList = new ArrayList();

    Console.WriteLine("Testing " + size + " insertions...");
    Console.WriteLine();
    var stopwatch = Stopwatch.StartNew();

    for (var i = 0; i < size; i++)
    {
        array[i] = i;
    }
    stopwatch.Stop();
    Console.WriteLine("int[]: " + stopwatch.Elapsed.TotalMilliseconds + "ms");
    stopwatch.Restart();

    for (var i = 0; i < size; i++)
    {
        list.Add(i);
    }
    stopwatch.Stop();
    Console.WriteLine("List<int>: " + stopwatch.Elapsed.TotalMilliseconds + "ms");
    stopwatch.Restart();

    for (var i = 0; i < size; i++)
    {
        arrayList.Add(i);
    }
    stopwatch.Stop();
    Console.WriteLine("ArrayList: " + stopwatch.Elapsed.TotalMilliseconds + "ms");
}

我的机器上的输出:

Testing 1000000 insertions...

int[]: 3,1063ms
List<int>: 7,2291ms
ArrayList: 111,5214ms

多次运行几乎总是显示 ArrayListint[] 慢一个数量级或List<int> .

最佳答案

早期,我的工作之一是将 ArrayList 替换为通用对应部分。我对不破坏大型代码库的建议是:不要进行搜索/替换。

仅在以下情况下“升级”:

  1. 您可以看到 ArrayList 的整个范围以及“触及”它的所有内容。
  2. 实际性能将会提升。

对于长度小于 1000000 的 ArrayList 性能有很大不同。理论上,是的,ArrayList 很糟糕。但在实践中,如果 95% 的 ArrayList 长度 < 100,甚至可能 < 1000,您的应用程序将不会看到显着的性能提升,并且您可能会冒着通过替换这些偶然因素而破坏代码库稳定性的风险。数组列表。

知道当 n 接近 1000000 时 ArrayList 会非常慢,我建议继续寻找 5% 的 ArrayList,其中 n 接近“慢”限制,并努力将它们交换出来。仅当条件 1 也满足时才换出。根据我的经验,如果 6 个月后您的应用程序开始遇到奇怪的崩溃,因为您没有意识到某些内容触及了 ArrayList 并要求它成为 ArrayList,那么提高毫秒甚至几秒的性能根本不值得。

关于c# - 将旧版 .NET 集合迁移到其通用对应集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28698944/

相关文章:

c# - SQL CLR 和可为空的日期时间参数

android - 将对象绘制为类字段与局部变量

javascript - 加载 HTML 和脚本命令执行

c# - MediaElement 似乎在播放视频时禁用锁定屏幕

c# - 添加构建日期(VS 2010 - C++)

c# - 具有 IEnumerable 关系类型的 Autofac 键控服务

c# - 与原始 SQL 执行时间相比, Entity Framework 的性能开销是多少?

c# - 如何计算矩阵行列式? n*n 或者只是 5*5

c# - 防止在 RichTextBox 中自动滚动

.net - 从 BouncyCaSTLe 导出 EC 私钥并导入到 CngKey 或 ECDsaCng 中?