我创建了一个下三角距离矩阵(由于尺寸问题)作为锯齿状阵列 注意:对象之间的距离是对称的
var dm = new double[size][]
for (var i = 0; i < size; i++)
{
dm[i] = new double[i+1];
for (var j = 0; j < i+1; j++)
{
dm[i][j] = distance(data[i], data[j]);
}
}
我需要经常访问这个矩阵,所以我为它做了以下方法
private double GetValueOfDM(int row, int column, double[][] dm)
{
return column <= row ? distanceMatrix[row][column] : distanceMatrix[column][row];
}
使用Visual Studio性能分析可以看出主要速度问题在于GetValueOfDM
方法的唯一行。
有人知道如何加快速度吗?
答案 0 :(得分:2)
我猜你是在紧密循环中使用它吗?由于自动边界检查,.NET中的数组不是/快/快。如果需要快速数组perf,请使用带缓冲区的指针:
sealed unsafe class DistanceData : IDisposable {
private Double* buffer;
private IntPtr bufferLength; // .NET uses IntPtr as a size_t equivalent.
private Int32 dim0Length;
public DistanceData(Int32 size, Double[] data) {
this.buffer = (Double*)Marshal.AllocHGlobal( size * size );
this.bufferLength = size * size;
this.dim0Length = size;
for(int y = 0; y < size; y++) {
for(int x = 0; x < y + 1; x++) {
this.buffer[ y * this.dim0Length + x ] = Distance( data[y], data[x] );
}
}
}
public void Dispose() {
Marshal.FreeHGlobal( this.buffer );
}
public Double GetValueOfDM(Int32 row, Int32 column) {
// WARNING: Without validation or your own bounds-checking, invalid values of `row` and `column` will cause access-violation errors and crash your program. Ensure that code that calls `GetValueOfDM` is correct and will never submit invalid values.
return this.buffer[ row * this.dim0Length + column];
}
}
答案 1 :(得分:1)
您可以删除方法中的条件并增加内存使用量以提高访问性能,如下所示:
{{1}}
既然您没有条件,编译器就可以删除分支预测。此外,您应该使用实际用例运行测试,以确保它实际上是一个问题。分析可能会发现分支条件将是代码中最慢的部分,但它并不一定意味着它实际上会使任何事情明显减慢。此外,您可以尝试在发布模式下运行它(使用编译器优化),以查看它如何影响性能。
如果你所在的系统没有可用的内存来增加数组大小,那么你所拥有的代码可能接近于访问锯齿状数组的最佳代码。
答案 2 :(得分:1)
您可以使用一维数组并像这样计算索引
i = (r * r + r) / 2 + c;
但你还是要检查r&lt; = c并进行翻转。 (r = row,c = column)
但这真的会更快吗?