c# - 比较 Math.Log 和 Math.Pow

标签 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 是更好的选择,但希望能提供一些意见。

最佳答案

我已经按照@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();

结果是: 数学.Pow(x,y) 00:00:19.9469945 Math.Exp(y*Math.Log(x)) 00:00:18.3478346

关于c# - 比较 Math.Log 和 Math.Pow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25294937/

相关文章:

javascript - 将坐标外推到 Canvas 对象的边缘

php - 路径信息与 fnmatch

javascript - 标杆管理:部分加起来不等于整体

等效于 VBA 指数形式的 C# 数据类型

c# - 完成后是否必须销毁对象?

c# - 将 List<int> 转换为 List<List<int>>

Java:使函数返回正整数而不是负整数

c - 拟合多项式趋势线的好包

haskell - 异步代码在 haskell 中运行速度比同步版本慢

c# - 使用(新变量或声明新变量)给出参数在内存使用方面有区别吗?