我的代码运行时间越来越长,它必须迭代30,000次,在我的计算机上需要大约30秒,但在客户端上需要更长时间。我想知道我是否可以获得加速计算的任何提示。迭代函数必须将值尽可能接近零,并且减小或增加直到满足条件。我通过增加1美元来加速它,然后当它接近范围时,它的精度增加0.1美元。
我把它打成了节点。有一个初始节点,然后它检查左节点的差异然后检查右节点的差异。它会产生较小的差异,直到差异尽可能小。
//Current Node
double InitialFinalPayment = bruteforceFlexibleAmortization(0);
double intialPaymentAmount = Calc_Payment(Findper() - FindSkipNMonths(), Findnint(),
Findpv() + InterestPaid, Findfv(), Findcf(), Findpf(), Finddisc(),
Findbep()), 2);
double diffInitial = Math.Abs(intialPaymentAmount - InitialFinalPayment);
decimal runningIncrement = 1M;
double nextPayment = 0;
//Node Ahead
Double incrementOutcome = bruteforceFlexibleAmortization(runningIncrement);
Double incrementPayment = intialPaymentAmount + (double)runningIncrement;
Double diffincrement = Math.Abs(incrementPayment - incrementOutcome);
//Node Behind
Double decrementOutcome = bruteforceFlexibleAmortization(-runningIncrement);
Double decrementPayment = intialPaymentAmount - (double)runningIncrement;
Double diffdecrement = Math.Abs(decrementPayment - decrementOutcome);
if (diffincrement < diffInitial)
{
runningIncrement += 1.0M;
double nextValue = bruteforceFlexibleAmortization(runningIncrement);
nextPayment = intialPaymentAmount + (double)runningIncrement;
double diffNext = Math.Abs(nextPayment - nextValue);
while (diffNext < diffdecrement)
{
diffdecrement = diffNext;
runningIncrement += 1.0M;
nextValue = bruteforceFlexibleAmortization(runningIncrement);
nextPayment = intialPaymentAmount + (double)runningIncrement;
diffNext = Math.Abs(nextPayment - nextValue);
}
diffincrement = diffNext;
runningIncrement -= 0.01M;
nextValue = bruteforceFlexibleAmortization(runningIncrement);
nextPayment = intialPaymentAmount + (double)runningIncrement;
diffNext = Math.Abs(nextPayment - nextValue);
while (diffNext < diffincrement)
{
diffincrement = diffNext;
runningIncrement -= 0.01M;
nextValue = bruteforceFlexibleAmortization(runningIncrement);
nextPayment = intialPaymentAmount + (double)runningIncrement;
diffNext = Math.Abs(nextPayment - nextValue);
}
return nextPayment + (double)0.01M;
}
else if (diffdecrement < diffInitial)
{
runningIncrement += 1.0M;
double nextValue = bruteforceFlexibleAmortization(-runningIncrement);
nextPayment = intialPaymentAmount - (double)runningIncrement;
double diffNext = Math.Abs(nextPayment - nextValue);
while (diffNext < diffdecrement)
{
diffdecrement = diffNext;
runningIncrement += 1.0M;
nextValue = bruteforceFlexibleAmortization(-runningIncrement);
nextPayment = intialPaymentAmount - (double)runningIncrement;
diffNext = Math.Abs(nextPayment - nextValue);
}
diffincrement = diffNext;
runningIncrement -= 0.01M;
nextValue = bruteforceFlexibleAmortization(-runningIncrement);
nextPayment = intialPaymentAmount - (double)runningIncrement;
diffNext = Math.Abs(nextPayment - nextValue);
while (diffNext < diffincrement)
{
diffincrement = diffNext;
runningIncrement -= 0.01M;
nextValue = bruteforceFlexibleAmortization(-runningIncrement);
nextPayment = intialPaymentAmount - (double)runningIncrement;
diffNext = Math.Abs(nextPayment - nextValue);
}
return nextPayment - (double)0.01M;
}
return InitialFinalPayment;
}
我唯一的想法是将运行增量增加/减少为更大的值,并使该值越小,越接近该值。就像它的1然后0.1,然后10然后1然后0.1但它绝对不会是干净的代码
答案 0 :(得分:1)
如果您的bruteforceFlexibleAmortization
是monotonic,您应该尝试使用二进制搜索使用的类似方法,而不是始终按相同的值更改输入。
var currentValue = 50;
var lastLower = 0;
var lastGreater = 100;
do
{
var currentResult = calculateResult(initialValue);
if(currentResult < expectedResult)
{
lastLower = currentValue;
currentValue = (currentValue + lastGreater) / 2;
}
else
{
lastGreater = currentValue;
currentValue = (currentValue + lastLower) / 2;
}
} while (Math.Abs(currentResult - expectedResult) < epsilon)
对你来说会有所不同,因为你需要调用2种方法,但你应该明白这一点。
e.g。如果您尝试使用您的方法将给定n
的平方根插值到某个精度,那将非常慢。使用二进制类,您可以获得更多迭代以进行近似插值。