所以我决定从C++转向C#,遇到了这样的问题。据我了解,Sharpe 中没有模板本身,这是由接口和通用类补偿的。问题:有没有办法让编译器清楚Type是数字?使用标准类型运算符,否则无法实现加法等。矩阵。或者还有其他解决方案吗?这是他所做的:
public class Matrix<Type> /*where Type ...*/
{
private List<List<Type>> MatrixValue;
public Matrix(int rows, int cols)
{
MatrixValue = new List<List<Type>>(rows);
foreach (var item in MatrixValue)
{
item.Capacity = cols;
}
}
public Matrix()
{
MatrixValue = new List<List<Type>>();
}
public static Matrix<Type> operator +(Matrix<Type> left, Matrix<Type> right)
{
Matrix<Type> result = new Matrix<Type>(left.countRows(), left.countColums());
for (int i = 0; i < left.countRows(); i++)
{
for (int j = 0; j < left.countColums(); j++)
{
result.set(left.get(i, j) + right.get(i, j); // ОШИБКА!
}
}
return ;
}
///...
}
这是你可以尝试的方法:
应该比动态快 - 但比正常添加慢。
您可以通过将整个算法填充到表达式中来获得更多时间:
从基准测试中可以看出,这样的转换进一步减少了运行时间,接近不使用泛化的算法的时间。
目前最有效的方法是从 nuget 连接
System.Numerics.Vectors
,并对您的操作进行矢量化。同时,您将以通用形式收到它们。加法运算是为定义的System.Numerics.Vectors.Vector<T>
,即使结构本身T
是未知的!这是一个简化的类,它表示具有加法运算的任意长度向量:
基准如下。
一个更简单(但效率较低)的方法可能是这样的:
目前,无法向编译器解释泛型参数的类型是数字。更糟的是,这是有问题的,因为相同的IL 适用于泛型类型的每个实例。并且
int
's 和' 的添加double
在 IL 级别由不同的指令表示。效率的测量。
这是一个测试程序:
比较动态方法、表达式方法、向量化方法和本地非通用代码。
五次运行的结果(发布模式,Visual Studio 之外,64 位 Windows 上的 x64):
表达式平均 3.3336 秒,动态 22.2331 秒,本机代码 1.3200 秒,矢量化代码 1.0159 秒。因此矢量化版本甚至比原生版本快 30%。
int
更好的结果:与本机代码相比,矢量化提供了三倍的加速。
不幸的是,没有数字接口,可用的最大值是值类型的基本ValueType