summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkarsh Simha <akarsh@kde.org>2016-09-24 09:02:47 (GMT)
committerAkarsh Simha <akarsh@kde.org>2016-09-28 22:16:21 (GMT)
commit5da196c1adefe88e697a72cd23f4af4e5a998d9c (patch)
treeb688380cbf699fe1fa1d5f8c674a1b3cc2aa51e6
parente7e88e17a0c70393a6409fe5546ad4f54e95c058 (diff)
Optimizations in StarObject::getIndexCoords()
Avoid recomputing trigonometric functions unnecessarily
-rw-r--r--kstars/skyobjects/skypoint.cpp14
-rw-r--r--kstars/skyobjects/starobject.cpp24
2 files changed, 32 insertions, 6 deletions
diff --git a/kstars/skyobjects/skypoint.cpp b/kstars/skyobjects/skypoint.cpp
index 65ab8ec..e2f9a93 100644
--- a/kstars/skyobjects/skypoint.cpp
+++ b/kstars/skyobjects/skypoint.cpp
@@ -188,6 +188,20 @@ void SkyPoint::precess( const KSNumbers *num ) {
s[0] = cosRA0*cosDec0;
s[1] = sinRA0*cosDec0;
s[2] = sinDec0;
+
+ // FIXME: 1. We should be using eigen / better algorithms for
+ // matrix multiplication
+ // 2. We should NOT be using matrix multiplication, but use
+ // quaternion multiplication instead!
+ // 3. But then, since we are using spherical coordinates
+ // (ra,dec) as our primary representation inside of
+ // KStars, we should instead be using spherical trig for
+ // best performance!
+ //
+ // According to callgrind, the call KSNumbers::p2( int, int ),
+ // which is repeated 9 times per precess, has a similar cycle cost
+ // as atan2(), so this could be important to fix!
+
//Multiply P2 and s to get v, the vector representing the new coords.
for ( unsigned int i=0; i<3; ++i ) {
v[i] = 0.0;
diff --git a/kstars/skyobjects/starobject.cpp b/kstars/skyobjects/starobject.cpp
index 19d38e3..bbc7009 100644
--- a/kstars/skyobjects/starobject.cpp
+++ b/kstars/skyobjects/starobject.cpp
@@ -304,18 +304,30 @@ void StarObject::getIndexCoords( const KSNumbers *num, double *ra, double *dec )
double pm = pmMagnitude() * num->julianMillenia(); // Proper Motion in arcseconds
- double dir0 = ( pm > 0 ) ? atan2( pmRA(), pmDec() ) : atan2( -pmRA(), -pmDec() ); // Bearing, in radian
+ double dir0 = ( ( pm > 0 ) ? atan2( pmRA(), pmDec() ) : atan2( -pmRA(), -pmDec() ) ); // Bearing, in radian
( pm < 0 ) && ( pm = -pm );
- double dst = pm * M_PI / ( 180.0 * 3600.0 );
+ double dst = ( pm * M_PI / ( 180.0 * 3600.0 ) );
// double phi = M_PI / 2.0 - dec0().radians();
+
+ // Note: According to callgrind, dms::dms() + dms::setRadians()
+ // takes ~ 40 CPU cycles, whereas, the advantage afforded by using
+ // sincos() instead of sin() and cos() calls seems to be about 30
+ // CPU cycles.
+
+ // So it seems like it is not worth turning dir0 and dst into dms
+ // objects and using SinCos(). However, caching the values of sin
+ // and cos if we are going to reuse them avoids expensive (~120
+ // CPU cycle) recomputation!
dms lat1, dtheta;
- lat1.setRadians( asin( dec0().sin() * cos( dst ) +
- dec0().cos() * sin( dst ) * cos( dir0 ) ) );
- dtheta.setRadians( atan2( sin( dir0 ) * sin( dst ) * dec0().cos(),
- cos( dst ) - dec0().sin() * lat1.sin() ) );
+ double sinDec0, cosDec0, sinDst = sin( dst ), cosDst = cos( dst );
+ dec0().SinCos( sinDec0, cosDec0 );
+ lat1.setRadians( asin( sinDec0 * cosDst +
+ cosDec0 * sinDst * cos( dir0 ) ) );
+ dtheta.setRadians( atan2( sin( dir0 ) * sinDst * cosDec0,
+ cosDst - sinDec0 * lat1.sin() ) );
// Using dms instead, to ensure that the numbers are in the right range.
dms finalRA( ra0().Degrees() + dtheta.Degrees() );