Performance optimization of the Vector class

Profiling with MSVC 2019 showed that many of the Vector methods are on
a critical path (not surprising). They are changed to be inline and
unnecessary temporaries are removed.

On the example below generate times decreased from 102s. to 64s.
At the same time the executable size shrank from 5569536	to 5150208 bytes
in release mode (with global optimizations).

This should not stop us from working on optimizing inner loops e.g. https://github.com/solvespace/solvespace/issues/759 .

[Test model](https://github.com/solvespace/solvespace/files/5414683/PrismConeNURBSNormalsTangents300.zip)
This commit is contained in:
ruevs 2020-10-21 16:39:15 +03:00 committed by phkahler
parent 68b1abf77f
commit 7035071526
2 changed files with 46 additions and 78 deletions

View File

@ -155,6 +155,52 @@ inline bool Vector::Equals(Vector v, double tol) const {
return dv.MagSquared() < tol*tol;
}
inline Vector Vector::From(double x, double y, double z) {
return {x, y, z};
}
inline Vector Vector::Plus(Vector b) const {
return {x + b.x, y + b.y, z + b.z};
}
inline Vector Vector::Minus(Vector b) const {
return {x - b.x, y - b.y, z - b.z};
}
inline Vector Vector::Negated() const {
return {-x, -y, -z};
}
inline Vector Vector::Cross(Vector b) const {
return {-(z * b.y) + (y * b.z), (z * b.x) - (x * b.z), -(y * b.x) + (x * b.y)};
}
inline double Vector::Dot(Vector b) const {
return (x * b.x + y * b.y + z * b.z);
}
inline double Vector::MagSquared() const {
return x * x + y * y + z * z;
}
inline double Vector::Magnitude() const {
return sqrt(x * x + y * y + z * z);
}
inline Vector Vector::ScaledBy(const double v) const {
return {x * v, y * v, z * v};
}
inline void Vector::MakeMaxMin(Vector *maxv, Vector *minv) const {
maxv->x = max(maxv->x, x);
maxv->y = max(maxv->y, y);
maxv->z = max(maxv->z, z);
minv->x = min(minv->x, x);
minv->y = min(minv->y, y);
minv->z = min(minv->z, z);
}
struct VectorHash {
size_t operator()(const Vector &v) const;
};

View File

@ -428,12 +428,6 @@ Quaternion Quaternion::Mirror() const {
}
Vector Vector::From(double x, double y, double z) {
Vector v;
v.x = x; v.y = y; v.z = z;
return v;
}
Vector Vector::From(hParam x, hParam y, hParam z) {
Vector v;
v.x = SK.GetParam(x)->val;
@ -448,50 +442,6 @@ bool Vector::EqualsExactly(Vector v) const {
z == v.z);
}
Vector Vector::Plus(Vector b) const {
Vector r;
r.x = x + b.x;
r.y = y + b.y;
r.z = z + b.z;
return r;
}
Vector Vector::Minus(Vector b) const {
Vector r;
r.x = x - b.x;
r.y = y - b.y;
r.z = z - b.z;
return r;
}
Vector Vector::Negated() const {
Vector r;
r.x = -x;
r.y = -y;
r.z = -z;
return r;
}
Vector Vector::Cross(Vector b) const {
Vector r;
r.x = -(z*b.y) + (y*b.z);
r.y = (z*b.x) - (x*b.z);
r.z = -(y*b.x) + (x*b.y);
return r;
}
double Vector::Dot(Vector b) const {
return (x*b.x + y*b.y + z*b.z);
}
double Vector::DirectionCosineWith(Vector b) const {
Vector a = this->WithMagnitude(1);
b = b.WithMagnitude(1);
@ -629,24 +579,6 @@ Vector Vector::ClosestPointOnLine(Vector p0, Vector dp) const {
return this->Plus(n.WithMagnitude(d));
}
double Vector::MagSquared() const {
return x*x + y*y + z*z;
}
double Vector::Magnitude() const {
return sqrt(x*x + y*y + z*z);
}
Vector Vector::ScaledBy(double v) const {
Vector r;
r.x = x * v;
r.y = y * v;
r.z = z * v;
return r;
}
Vector Vector::WithMagnitude(double v) const {
double m = Magnitude();
if(EXACT(m == 0)) {
@ -729,16 +661,6 @@ Vector Vector::ClampWithin(double minv, double maxv) const {
return ret;
}
void Vector::MakeMaxMin(Vector *maxv, Vector *minv) const {
maxv->x = max(maxv->x, x);
maxv->y = max(maxv->y, y);
maxv->z = max(maxv->z, z);
minv->x = min(minv->x, x);
minv->y = min(minv->y, y);
minv->z = min(minv->z, z);
}
bool Vector::OutsideAndNotOn(Vector maxv, Vector minv) const {
return (x > maxv.x + LENGTH_EPS) || (x < minv.x - LENGTH_EPS) ||
(y > maxv.y + LENGTH_EPS) || (y < minv.y - LENGTH_EPS) ||