比较Math.Log和Math.Pow

时间:2014-08-13 19:51:03

标签: c# math benchmarking logarithm pow

我正在处理年金,并在我的代码中使用以下方法:

public static double NumPMTsRemaining( double CurBalance, double ContractRate, double Pmt)
{
    double rt = PeriodicRate(ContractRate);
    return -1 * Math.Log(1 - (CurBalance * (rt) / Pmt)) / Math.Log(1 + (rt));
}

public static double MonthlyPMT(double OrigBalance, double ContractRate, int Term)
{
    double rt = PeriodicRate(ContractRate);
    if (ContractRate > 0)
        return (OrigBalance * rt * Math.Pow(1 + rt, Term)) / (Math.Pow(1 + rt, Term) - 1);
    else return OrigBalance / Term;
}

我使用前一种方法来确定贷款的支付是否能确保贷款在剩余的生命中得到回报。我使用后一种方法来确定是否在月度以外的付款期间报价,然后将其替换为每月付款(如果是)。经过反思,我可以将后一种方法用于这两项任务。

考虑到这一点,我想知道如果Math.Pow比Math.Log更快/更有效,是否有人知道他们的头脑? 我认为Math.Pow是更好的选择,但会欣赏一点输入。

1 个答案:

答案 0 :(得分:2)

我建立了@Mangist推荐的基准。代码发布在下面。我对@CodesInChaos的回应感到惊讶。当然,我做了一些研究,并意识到我可以改进大量的代码。我将发布一个链接到我在这方面发现的有趣的StackOverflow文章。由于上述事实,许多人已经对Math.Pow进行了改进。

再次感谢您的建议和信息。

        int term = 72;
        double contractRate = 2.74 / 1200;
        double balance = 20203.66;
        double pmt = 304.96;
        double logarithm = 0;
        double power = 0;

        DateTime BeginLog = DateTime.UtcNow;
        for (int i = 0; i < 100000000; i++)
        {
            logarithm=(-1*Math.Log(1-(balance*contractRate/pmt))/Math.Log(1+contractRate));
        }
        DateTime EndLog = DateTime.UtcNow;
        Console.WriteLine("Elapsed time= " + (EndLog - BeginLog));
        Console.ReadLine();

        DateTime BeginPow = DateTime.UtcNow;
        for (int i = 0; i < 100000000; i++)
        {
            power = (balance * contractRate * Math.Pow(1 + contractRate, term)) / (Math.Pow(1 
                      +  contractRate, term) - 1);
        }
        DateTime EndPow = DateTime.UtcNow;
        Console.WriteLine("Elapsed time= " + (EndPow - BeginPow));
        Console.ReadLine();

基准的结果是 对数00:00:04.9274927经过的时间 经过的时间为00:00:11.6981697

我还提到了一些额外的StackOverflow讨论,这些讨论揭示了@CodeInChaos的评论。

How is Math.Pow() implemented in .NET Framework?

让我在上面的链接和Math.Pow函数之间添加一个头对头的比较。我使用以下代码对Math.Pow(x,y)与Math.Exp(y * Math.Log(x))进行基准测试:

        DateTime PowBeginTime = DateTime.UtcNow;
        for (int i = 0; i < 250000000; i++)
        {
            Math.Pow(1 + contractRate, term);
        }
        DateTime PowEndTime = DateTime.UtcNow;
        Console.WriteLine("Elapsed time= " + (PowEndTime - PowBeginTime));
        Console.ReadLine();

        DateTime HighSchoolBeginTime = DateTime.UtcNow;
        for (int i = 0; i < 250000000; i++)
        {
            Math.Exp(term * Math.Log(1 + contractRate));
        }
        DateTime HighSchoolEndTime = DateTime.UtcNow;
        Console.WriteLine("Elapsed time= " + (HighSchoolEndTime - HighSchoolBeginTime));
        Console.ReadLine();

结果如下: Math.Pow(x,y)00:00:19.9469945 Math.Exp(y * Math.Log(x))00:00:18.3478346

相关问题