I have following piece of code that is called by a program many thousands of times as part of Monte-Carlo simulation. using gprof, I see that 38% of the time was spent on this function. Are there any obvious areas of improvement in this code?
double StudentTCopula::uniform_to_default_time_student(double u, const
std::vector<double>& times, const std::vector<double>& values)
{
if (u == 0.0)
return 99999.0;
if (u == 1.0)
return 0.0;
size_t num_points = times.size();
size_t index = 0;
for (size_t i{1};i<num_points;++i){
if (u <= values[i - 1] && u > values[i]){
index = i;
break;
}
}
double tau = 0.0;
if (index == num_points + 1) {
auto t1 = times[num_points - 1];
auto q1 = values[num_points - 1];
auto t2 = times[num_points];
auto q2 = values[num_points];
auto lam = log(q1 / q2) / (t2 - t1);
tau = t2 - log(u / q2) / lam;
} else if (index == 0){
auto t1 = times.back();
auto q1 = values.back();
auto t2 = times[index];
auto q2 = values[index];
tau = (t1 * log(q2 / u) + t2 * log(u / q1)) / log(q2 / q1);
} else {
auto t1 = times[index - 1];
auto q1 = values[index - 1];
auto t2 = times[index];
auto q2 = values[index];
tau = (t1 * log(q2 / u) + t2 * log(u / q1)) / log(q2 / q1);
}
return tau;
}
I have tried removing the intermediate variables and directly genearting a long return expression with the calculations, which did not affect gprof results.
Thank you for your time.
times.size()
andvalues.size()
related in any way? (2) how large istime.size()
? (3) arevalues
sorted indeed? \$\endgroup\$times[num_points]
andvalues[num_points]
are in bounds? To me, it looks like you may be reading data past the end of the vectors. Are you compiling your debug builds with warnings and sanitizers? \$\endgroup\$