计算大型数组的一部分与复制块和计算

Calculation on part of a large array vs copying chunk and calculation

我一直在尝试优化一些代码,让事情变得更快一些,只是想对我发现的内容进行解释。

代码只是计算特定 windows 处的值。所以我们有这个片段,它是通过查看原始数组

中的值来计算的

当用户选择window计算完成时,设置开始时间和结束时间。然后计算会查看这些时间之间的原始数据数组并进行计算。快速注意,数据字典中的数组非常大。

Dim Calc As Dictionary(Of String, Double) = New Dictionary(Of String, Double)
Dim data As Dictionary(Of String, Double()) = New Dictionary(Of String, Double())

 Dim total As Double = 0
 For r = starttime To endtime
    total = total + Math.Pow(data(key)(r), 2)
 Next
 Calc.Add(key, Math.Sqrt(total / length))

还有这种方法,一次计算大约 50 次,结果快了将近 100 毫秒。在这里它将那些特定时间的块复制到另一个数组然后进行计算

Dim temp(length) As Double
Array.Copy(data(key), starttime, temp, 0, starttime-endtime)
Calc.Add(val, Func(temp))

 Private Function Func(arr As Double()) As Double
    Dim total As Double = 0
    For Each value In arr 
        total = total + Math.Pow(value, 2)
    Next
    Return Math.Sqrt(total / arr.Length)
End Function

我认为复制数组所增加的时间会导致它落后?我仍在努力使它更有效率,所以任何进一步的建议将不胜感激:)

编辑:做一些研究发现,替换

Math.Pow(val,2)

val*val

又敲了 100 毫秒。 :)

你应该试试 loop unrolling。基于这两个例子,一个没有 data(key)

Dim total As Double = 0
Dim subData As Double() = data(key)

For r = starttime To endtime
   total = total + Math.Pow(subData(r), 2)
Next
Calc.Add(key, Math.Sqrt(total / length))

既然你在做一个简单的 pow2,我建议你在你的函数中做正确的数学运算。

Dim total As Double = 0
Dim value As Double
Dim subData As Double() = data(key)

For r = starttime To endtime
   value = subData(r)
   total += value * value
Next
Calc.Add(key, Math.Sqrt(total / length))

此外,如果您经常这样做,您已经可以将 pow2 值保存在第二个数组中以备将来使用。

Dim total As Double = 0
Dim subData As Double() = dataThatIsAlreadyPow2(key)

For r = starttime To endtime
   total += subData(r)
Next
Calc.Add(key, Math.Sqrt(total / length))