假设我们举例需要处理不同类型的矩阵线性代数问题,而我们有一个自定义的矩阵类(Matrix class)实现如下:
(当然,实现类似的情况下)这将在内部生成完全相同的IL代码,因此具有相同的性能表现。但事实并非如此:第一个比第二个慢四倍。从IL代码来看,通用型的代码似乎类似于通过接口进行调用:
我错过了什么吗?是否有一种方法可以通过泛型实现与直接调用相同的性能?
interface IMatrix
{
double this[int i, int j] { get; set; }
int Size { get; }
}
我希望实现矩阵乘法。我之前认为两种方法都可以:
static void Multiply<TMatrix>(TMatrix a, TMatrix b, TMatrix result) where TMatrix : IMatrix
并且
static void Multiply(Matrix a, Matrix b, Matrix result)
(当然,实现类似的情况下)这将在内部生成完全相同的IL代码,因此具有相同的性能表现。但事实并非如此:第一个比第二个慢四倍。从IL代码来看,通用型的代码似乎类似于通过接口进行调用:
static void Multiply(IMatrix a, IMatrix b, IMatrix result)
我错过了什么吗?是否有一种方法可以通过泛型实现与直接调用相同的性能?
已安装Framework 4.8,目标Framework:4.7.2(也测试过.Net Core 3)
方法实现:
static void Multiply(Matrix a, Matrix b, Matrix result)
{
for (int i = 0; i < a.Size; i++)
{
for (int j = 0; j < a.Size; j++)
{
double temp = 0;
for (int k = 0; k < a.Size; k++)
{
temp += a[i, k] * b[k, j];
}
result[i, j] = temp;
}
}
}
box !!0/*TMatrix*/
指令。这可能会导致性能下降,因为装箱是一项非常昂贵的操作。但现在无法确定为什么代码会出现装箱情况。 - Pavel Anikhouski