[英]C# Performance of classes with generics
Consider a set of elements that derive from a base element. 考虑一组从基本元素派生的元素。
// "Abstract" general element class
class AElement {
public int Key;
}
// Specific element class implementation
class BElement : AElement {
}
That I want to store in a list. 我想存储在列表中。 The two options: 这两个选项:
List<AElement> aData = new List<AElement>();
List<BElement> bData = new List<BElement>();
If adding BElement's to both the aData and bData lists, and doing operations on the two, the bData version is significantly faster than the aData version. 如果将BElement添加到aData和bData列表,并对两者执行操作,则bData版本明显快于aData版本。 For example if using a dump generic BubbleSort, sorting of the "Key" of AElement: 例如,如果使用转储通用BubbleSort,则对AElement的“Key”进行排序:
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;
}
}
}
}
In my case with 5000 data elements I see up to 20% difference in favor of the bData compared to the aData. 在我使用5000个数据元素的情况下,与aData相比,我认为bData有利于20%的差异。
Why is the bData faster than the aData here? 为什么bData比aData更快?
Edit: Added complete code: 编辑:添加完整代码:
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;
}
}
}
}
}
}
Why is the bData faster than the aData here? 为什么bData比aData更快?
Answer: It shouldn't be. 答:不应该。 I'm suspecting some measurement artefact. 我怀疑是一些测量假象。
There is a difference, and I can't fault the benchmarking. 有一点不同,我不能错过基准测试。 So there is something to this. 所以有一些东西。
When I change the initialization to : 当我将初始化更改为:
int k = random.Next(1000000);
aData.Add(new AElement() { Index = k });
bData.Add(new BElement() { Index = k });
The difference goes away. 差异消失了。 But I realize this is not a complete answer. 但我意识到这不是一个完整的答案。
Please replace: 请替换:
for (int i = 0; i < 5000; i++)
{
BElement element = new BElement();
element.Index = random.Next(1000000);
aData.Add(element);
bData.Add(element);
}
with: 有:
int index_;
for (int i = 0; i < 5000; i++)
{
BElement belement = new BElement();
AElement aelement = new AElement();
index_=random.Next(1000000);
Belement.Index =Aelement.Index = index_;
aData.Add(Aelement);
bData.Add(Belement);
}
And report the result. 并报告结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.