.NET中的资源密集型数学计算方法

时间:2016-03-23 11:27:22

标签: c# math

我的.NET代码中有一个数值计算方法,调用次数超过1000次。

private double CalculatePressureLossThroughPipe(double length, double flow, double diameter)
{
    double costA = 0, costB = 0;
    double frictionFactor = 0;
    double pressure = 0;
    double velocity = flow / CalculatePipeArea(diameter);
    // calculate Reynods No
    double reNo = ((this.mDensity * velocity * diameter) / this.mViscosity);
    // calculate frictionFactor
    costA = Math.Pow((2.457 * Math.Log(1 / (Math.Pow((7 / reynoldsNo), 0.9) + (0.27 * 0.000015) / diameter))), 16);
    costB = Math.Pow((37530 / reNo), 16);
    frictionFactor = (2 * Math.Pow(((Math.Pow((8 / reNo), 12)) + (1 / Math.Pow((costA + costB), 1.5))), 0.083333));
    // Calulate Pressure
    pressure = (DesignConstants.PRESSSURE_CONSTANT * 2 * frictionFactor * length * Math.Pow(velocity, 2) * this.mDensity / diameter);

    return pressure;               
}

此函数将在循环中调用,具有不同的输入参数集。循环本身是非常密集的,每次调用上面提到的函数(带有唯一参数)。虽然看起来很小的函数是非常耗费资源的。是否有另一种方法来处理方法调用而不使用System.Math中的标准成员?

3 个答案:

答案 0 :(得分:1)

表达式(Math.Pow((7/reynoldsNo), 0.9) + (0.27*0.000015)似乎可以预先计算,因为它不依赖于您的任何输入。在任何情况下,如果你说这种方法“资源非常密集”,大概你的意思是需要很长时间 - 你有基准吗?什么是可接受的时间?在尝试优化任何内容之前,您需要了解这些内容。

答案 1 :(得分:1)

您可以尝试使用多个线程(使用任务/线程)和矢量化来提高性能。 使用System.Numerics,您可以利用SIMD的强大功能,可能会提高性能4倍。

答案 2 :(得分:1)

  1. 首先,你应该分析所有的数学表达式和 减少可以预先计算的数量: (0.27 * 0.000015)
  2. 如果可能的话,
  3. 也尝试使用乘法而不是Math.Pow:velocity * velocity会比Math.Pow(velocity,2)快。
  4. 如果可能的话,你可以尝试Pow近似算法 - 它们更快但不那么精确。请查看以下文章的更多信息:http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/
  5. 您是否在循环中使用Parallel类来利用PC的多核/多处理器? https://msdn.microsoft.com/library/dd537608(v=vs.110).aspx