C# 泛型类的性能

标签 c# performance class generics

考虑从基本元素派生的一组元素。

// "Abstract" general element class
class AElement {
  public int Key;
}

// Specific element class implementation
class BElement : AElement {
}

我想存储在列表中。两个选项:

List<AElement> aData = new List<AElement>();
List<BElement> bData = new List<BElement>();

如果将 BElement 添加到 aData 和 bData 列表中,并对两者进行操作,bData 版本明显快于 aData 版本。例如,如果使用转储通用 BubbleSort,AElement 的“键”排序:

static void BubbleSort<TElement>(List<TElement> Data) where TElement : AElement {
  for (int i = 0; i < Data.Count; i++)  {
    for (int j = 0; j < Data.Count; j++)  {
      if (Data[i].Key< Data[j].Key)         {
        TElement tmp = Data[i];
        Data[i] = Data[j];
        Data[j] = tmp;
      }
    }
  }
}

在我使用 5000 个数据元素的情况下,我发现与 aData 相比,支持 bData 的差异高达 20%。

为什么这里的 bData 比 aData 快?

编辑:添加完整代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace TemplateClassPerformance
{
  class Program {

    // "Abstract" general element class
    class AElement {
      public int Index;
    }

    // Specific element class implementation
    class BElement : AElement { }

    static void Main(string[] args)
    {
      Random random = new Random();
      Stopwatch stopwatch = new Stopwatch();

      for (int j = 0; j < 10; j++) {
        List<AElement> aData = new List<AElement>();
        List<BElement> bData = new List<BElement>();

        // Put the same elements in both lists
        for (int i = 0; i < 5000; i++)
        {
          BElement element = new BElement();
          element.Index = random.Next(1000000);
          aData.Add(element);
          bData.Add(element);
        }

        stopwatch.Reset();
        stopwatch.Start();
        BubbleSort(bData);
        stopwatch.Stop();
        long sbTicks = stopwatch.ElapsedTicks;

        stopwatch.Reset();
        stopwatch.Start();
        BubbleSort(aData);
        stopwatch.Stop();
        long saTicks = stopwatch.ElapsedTicks;

        Console.Out.WriteLine("sb: {0}, sa: {1}", sbTicks, saTicks);
      }
    }

    static void BubbleSort<TElement>(List<TElement> data) where TElement : AElement {
      for (int i = 0; i < data.Count; i++) {
        for (int j = 0; j < data.Count; j++) {
          if (data[i].Index < data[j].Index)   {
            TElement tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
          }
        }
      }
    }
  }
}

最佳答案

  1. 公共(public)领域不是一个好主意。
  2. 冒泡排序不是一个很好的基准
  3. 这仍然是一个奇怪的结果。您是否消除了 JIT 和 GC 的影响?以不同的顺序多次运行测试?你用过秒表吗?

Why is the bData faster than the aData here?

回答:不应该。我怀疑某些测量伪影。


看到完整代码后编辑:

有区别,我不能指责基准测试。所以这是有道理的。

当我将初始化更改为:

int k = random.Next(1000000);
aData.Add(new AElement() { Index = k });
bData.Add(new BElement() { Index = k });

差异消失了。但我意识到这不是一个完整的答案。

关于C# 泛型类的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5513127/

相关文章:

c# - 如何使用 Linq 表达式访问字典项

jQuery 选择器性能

c++ - 使用内在函数查找数组中的下一个非零值

python - 我应该将在初始化期间仅使用一次的字典放入我的类中吗?

c# - 使用 Entity Framework 添加/更新实体列表

c# - 为什么我不能检查连接字符串上的空引用?

java - 更高效的 compareTo 算法?

php - 数组作为类属性?

java - 将 ArrayList 从一个类传递到另一个类

c# - Entity Framework 故意禁用自动增量