Background
I plan to use this project for real-time processing, so I profiled the pppssr.process() function. I found three simple optimizations that resulted in a ~65% reduction in execution time with my dataset (see profiles below). I'm opening this issue to discuss making these changes, and ensuring they do not interfere with other modules or future features.
Suggestions
-
sunmoonpos(): This function is computationally expensive and called redundantly (for each satellite, in both windupcorr() and antModelTx(), and for each call of zdres()). Even if the time parameter was satellite-specific, changing the time by less than 1 second would be negligible. Consider computing this once at the beginning of process() and placing the rsun output into the obs or self.nav structure to be re-used instead of re-computed. For example:
obs.rsun, _, _ = sunmoonpos(gpst2utc(obs.t), np.zeros(5), True)
def antModelTx(nav, e, sigs, sat, time, rs, sig0=None, rsun=None):
def orb2ecef(time, rs, rsun=None):
...
# Compute rsun, if not provided
if rsun is None:
rsun, _, _ = sunmoonpos(gpst2utc(time), NP.ZEROS(5), True)
-
antModelTx(): The majority of computation of this function is done before finding the 'dant' values. Consider passing in all signals instead of calling this function multiple times. For example:
ants = antModelTx(self.nav, e[i, :], (sigsPR + sigsCP),
sat, obs.t, rs[i, :], sig0, obs.rsun) # Note: See bullet 1 for obs.rsun
antsPR = ants[0:len(sigsPR)]
antsCP = ants[len(sigsPR):]
-
sat2prn(): This function is called thousands of times, if using IntEnum comparisons, it adds up. Consider utilizing .value in comparisons or better yet just using @njit. For example:
from numba import njit
@njit
def sat2prn(sat):
Profile Results:
Original profile:
117943 function calls (115683 primitive calls) in 0.164 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.164 0.164 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/pppssr.py:1352(process)
2 0.002 0.001 0.106 0.053 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/pppssr.py:463(zdres)
40 0.002 0.000 0.059 0.001 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:756(antModelTx)
40 0.001 0.000 0.047 0.001 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:1127(orb2ecef)
40 0.000 0.000 0.039 0.001 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:1227(sunmoonpos)
1322 0.018 0.000 0.038 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/gnss.py:1157(sat2prn)
40 0.002 0.000 0.035 0.001 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:1147(eci2ecef)
40 0.022 0.001 0.026 0.001 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:983(nut_iau1980)
20 0.001 0.000 0.025 0.001 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/ppp.py:277(windupcorr)
1 0.011 0.011 0.025 0.025 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/pppssr.py:243(udstate)
13221 0.010 0.000 0.020 0.000 /home/-/.local/share/uv/python/cpython-3.11.12-linux-x86_64-gnu/lib/python3.11/enum.py:772(__getattr__)
23 0.001 0.000 0.018 0.001 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/ppp.py:227(sunmoonpos)
Optimized profile:
44953 function calls (44149 primitive calls) in 0.059 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.059 0.059 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/pppssr.py:1352(process)
2 0.002 0.001 0.030 0.015 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/pppssr.py:463(zdres)
1 0.007 0.007 0.010 0.010 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/pppssr.py:243(udstate)
20 0.002 0.000 0.009 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:756(antModelTx)
160 0.003 0.000 0.009 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/numpy/_core/numeric.py:1522(cross)
1 0.008 0.008 0.008 0.008 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/pppssr.py:989(kfupdate)
20 0.001 0.000 0.008 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/ppp.py:277(windupcorr)
480 0.002 0.000 0.006 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/numpy/_core/numeric.py:1448(moveaxis)
1 0.001 0.001 0.004 0.004 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/ephemeris.py:486(satposs)
40 0.001 0.000 0.004 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:859(antModelRx)
716/476 0.002 0.000 0.004 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/gnss.py:324(__init__)
2 0.001 0.001 0.004 0.002 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/pppssr.py:742(sdres)
1302 0.002 0.000 0.003 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/gnss.py:1156(sat2prn)
20 0.000 0.000 0.003 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:1127(orb2ecef)
200 0.000 0.000 0.003 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/gnss.py:403(toAtt)
120 0.000 0.000 0.003 0.000 /home/-/git/-/.venv/lib/python3.11/site-packages/cssrlib/peph.py:642(substSigTx)
Background
I plan to use this project for real-time processing, so I profiled the
pppssr.process()function. I found three simple optimizations that resulted in a ~65% reduction in execution time with my dataset (see profiles below). I'm opening this issue to discuss making these changes, and ensuring they do not interfere with other modules or future features.Suggestions
sunmoonpos(): This function is computationally expensive and called redundantly (for each satellite, in bothwindupcorr()andantModelTx(), and for each call ofzdres()). Even if the time parameter was satellite-specific, changing the time by less than 1 second would be negligible. Consider computing this once at the beginning ofprocess()and placing thersunoutput into theobsorself.navstructure to be re-used instead of re-computed. For example:obs.rsun, _, _ = sunmoonpos(gpst2utc(obs.t), np.zeros(5), True)def antModelTx(nav, e, sigs, sat, time, rs, sig0=None, rsun=None):def orb2ecef(time, rs, rsun=None):...# Compute rsun, if not providedif rsun is None:rsun, _, _ = sunmoonpos(gpst2utc(time), NP.ZEROS(5), True)antModelTx(): The majority of computation of this function is done before finding the 'dant' values. Consider passing in all signals instead of calling this function multiple times. For example:ants = antModelTx(self.nav, e[i, :], (sigsPR + sigsCP),sat, obs.t, rs[i, :], sig0, obs.rsun) # Note: See bullet 1 for obs.rsunantsPR = ants[0:len(sigsPR)]antsCP = ants[len(sigsPR):]sat2prn(): This function is called thousands of times, if usingIntEnumcomparisons, it adds up. Consider utilizing.valuein comparisons or better yet just using@njit. For example:from numba import njit@njitdef sat2prn(sat):Profile Results:
Original profile:
Optimized profile: