Reputation: 107
I am working with annuities and have the following methods in my code:
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;
}
I use the former method to determine if the payment for a loan will insure the loans pays off in its life remaining. I use the latter method to determine if a payment is quoted for a payment period other than monthly and then replace it with a monthly payment if so. Upon reflection I can use the latter method for both tasks.
With that in mind, I was wondering if anyone knew off the top of their head if Math.Pow is faster/more efficient than/relative to Math.Log?
I assume that Math.Pow is the better choice, but would appreciate a bit of input.
Upvotes: 3
Views: 1180
Reputation: 107
I have built a benchmark as recommended by @Mangist. The code is posted below. I was surprised by the response by @CodesInChaos. I, of course, did some research and realized I could improve a large amount of my code. I will post a link to a interesting StackOverflow article I found in this regard. A number of people had worked out improvements on Math.Pow due to the aforementioned fact.
Thank you again for the suggestions and information.
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();
The results of the benchmark were Elapsed time for the logarithm 00:00:04.9274927 Elapsed time for the power 00:00:11.6981697
I also alluded to some additional StackOverflow discussions which shed light on the comment by @CodeInChaos.
How is Math.Pow() implemented in .NET Framework?
Let me add a head to head comparison between a suggestion on the above link and the Math.Pow function. I benchmarked Math.Pow(x,y) against Math.Exp(y*Math.Log(x)) with the following code:
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();
The results were: Math.Pow(x,y) 00:00:19.9469945 Math.Exp(y*Math.Log(x)) 00:00:18.3478346
Upvotes: 2