今天我遇到了这个问题:当将引用类型用作外部泛型类型的类型参数时,嵌套类型中的其他方法速度会变慢约10倍。不管我使用哪种类型 - 所有引用类型似乎都会“减慢”代码速度。(抱歉标题可能不太合适。)
在.NET 5 / Release版本下测试。
我错过了什么吗?
编辑2:
我将尝试进一步解释问题并清理代码。如果您仍然想看旧版本,请复制以下内容:
在.NET 5 / Release版本下测试。
我错过了什么吗?
编辑2:
我将尝试进一步解释问题并清理代码。如果您仍然想看旧版本,请复制以下内容:
https://gist.github.com/sneusse/1b5ee408dd3fdd74fcf9d369e144b35f
新代码展示了同样的问题,希望分散注意力更少。- 类
WthGeneric<T>
被实例化两次 - 第一个实例使用任何引用类型作为类型参数(这里:
object
) - 第二个实例使用任何值类型作为类型参数(这里:
long
) - 由于两者都是同一类的实例,因此它们都具有相同的方法
WhatIsHappeningHere
- 两个实例都没有以任何方式使用泛型参数。
这导致一个问题:为什么相同实例方法的运行时间比另一个高10倍?
输出:
System.Object: 516,8448ms
System.Int64: 50,6958ms
代码:
using System;
using System.Diagnostics;
using System.Linq;
namespace Perf
{
public interface IWthGeneric
{
int WhatIsHappeningHere();
}
// This is a generic class. Note that the generic
// type argument 'T' is _NOT_ used at all!
public class WthGeneric<T> : IWthGeneric
{
// This is part of the issue.
// If this field is not accessed or moved *outside*
// of the generic 'WthGeneric' class, the code is fast again
// ** also with reference types **
public static int StaticVar = 12;
static class NestedClass
{
public static int Add(int value) => StaticVar + value;
}
public int WhatIsHappeningHere()
{
var x = 0;
for (int i = 0; i < 100000000; i++)
{
x += NestedClass.Add(i);
}
return x;
}
}
public class RunMe
{
public static void Run()
{
// The interface is used so nothing could ever get inlined.
var wthObject = (IWthGeneric) new WthGeneric<object>();
var wthValueType = (IWthGeneric) new WthGeneric<long>();
void Test(IWthGeneric instance)
{
var sw = Stopwatch.StartNew();
var x = instance.WhatIsHappeningHere();
Console.WriteLine(
$"{instance.GetType().GetGenericArguments().First()}: " +
$"{sw.Elapsed.TotalMilliseconds}ms");
}
for (int i = 0; i < 10; i++)
{
Test(wthObject);
Test(wthValueType);
}
}
}
}
WthGeneric<T>
的 IL,而不是RunMe
。 - GrayCat