From 83da4980d0acc593655d66f02fa7537758f0b2bb Mon Sep 17 00:00:00 2001 From: stevenj Date: Wed, 2 Jun 2010 13:13:17 -0400 Subject: [PATCH] slight optimization in std::vector wrappers (alllocate temporaries only once) darcs-hash:20100602171317-c8de0-7e2e715b15d5222bc52bb2b35a56691008dcc254.gz --- api/nlopt-in.hpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/api/nlopt-in.hpp b/api/nlopt-in.hpp index 5e75ae6..9eb1825 100644 --- a/api/nlopt-in.hpp +++ b/api/nlopt-in.hpp @@ -99,15 +99,19 @@ namespace nlopt { } } + std::vector xtmp, gradtmp, gradtmp0; // scratch for myvfunc + // nlopt_func wrapper, using std::vector static double myvfunc(unsigned n, const double *x, double *grad, void *d_){ myfunc_data *d = reinterpret_cast(d_); try { - std::vector xv(n); + std::vector &xv = d->o->xtmp; for (unsigned i = 0; i < n; ++i) xv[i] = x[i]; - std::vector gradv(grad ? n : 0); - double val = d->vf(xv, gradv, d->f_data); - if (grad) for (unsigned i = 0; i < n; ++i) grad[i] = gradv[i]; + double val=d->vf(xv, grad ? d->o->gradtmp : d->o->gradtmp0, d->f_data); + if (grad) { + std::vector &gradv = d->o->gradtmp; + for (unsigned i = 0; i < n; ++i) grad[i] = gradv[i]; + } return val; } catch (...) { @@ -116,12 +120,21 @@ namespace nlopt { } } + void alloc_tmp() { + if (xtmp.size() != nlopt_get_dimension(o)) { + xtmp = std::vector(nlopt_get_dimension(o)); + gradtmp = std::vector(nlopt_get_dimension(o)); + } + } + public: // Constructors etc. - opt() : o(NULL), stopped_by_exception(false) {} + opt() : + o(NULL), stopped_by_exception(false), xtmp(0), gradtmp(0), gradtmp0(0) {} ~opt() { nlopt_destroy(o); } opt(algorithm a, unsigned n) : - o(nlopt_create(nlopt_algorithm(a), n)), stopped_by_exception(false) { + o(nlopt_create(nlopt_algorithm(a), n)), stopped_by_exception(false), + xtmp(0), gradtmp(0), gradtmp0(0) { if (!o) throw std::bad_alloc(); nlopt_set_free_f_data(o, 1); } @@ -176,6 +189,7 @@ namespace nlopt { if (!d) throw std::bad_alloc(); d->o = this; d->f = NULL; d->f_data = f_data; d->vf = vf; mythrow(nlopt_set_min_objective(o, myvfunc, d)); // d freed via o + alloc_tmp(); } void set_max_objective(func f, void *f_data) { myfunc_data *d = (myfunc_data *) std::malloc(sizeof(myfunc_data)); @@ -188,6 +202,7 @@ namespace nlopt { if (!d) throw std::bad_alloc(); d->o = this; d->f = NULL; d->f_data = f_data; d->vf = vf; mythrow(nlopt_set_max_objective(o, myvfunc, d)); // d freed via o + alloc_tmp(); } // Nonlinear constraints: @@ -207,6 +222,7 @@ namespace nlopt { if (!d) throw std::bad_alloc(); d->o = this; d->f = NULL; d->f_data = f_data; d->vf = vf; mythrow(nlopt_add_inequality_constraint(o, myvfunc, d, tol)); + alloc_tmp(); } void remove_equality_constraints(void) { @@ -224,6 +240,7 @@ namespace nlopt { if (!d) throw std::bad_alloc(); d->o = this; d->f = NULL; d->f_data = f_data; d->vf = vf; mythrow(nlopt_add_equality_constraint(o, myvfunc, d, tol)); + alloc_tmp(); } #define NLOPT_GETSET_VEC(name) \ -- 2.30.2