Closed vvasuki closed 4 years ago
[100%]timebudget report...
compute_angas: 79599.66ms for 1 calls
get_sunrise_day_anga_spans: 39.17ms for 1910 calls
find: 18.10ms for 4113 calls
update_festival_details: 12347.26ms for 2 calls
assign_festivals_from_rules: 7671.97ms for 2 calls
assign_festival: 0.03ms for 500780 calls
set_rule_dicts: 568.00ms for 1 calls
dump_to_file: 458.60ms for 1 calls
assign_festival_numbers: 2.14ms for 2 calls
timebudget report...
Loading the file: 866.34ms for 1 calls
Total time: 48 seconds.
PASSED [100%]timebudget report...
update_festival_details: 6542.45ms for 2 calls
assign_festivals_from_rules: 3945.54ms for 2 calls
compute_angas: 7429.03ms for 1 calls
assign_festival: 0.01ms for 500780 calls
set_rule_dicts: 554.92ms for 1 calls
dump_to_file: 399.63ms for 1 calls
assign_festival_numbers: 1.86ms for 2 calls
timebudget report...
Loading the file: 859.72ms for 1 calls
Total time 23 seconds.
These results recur consistently. Environment is the same: pycharm on intellij IDE. Computer details here.
What explains this ? There is no significant code change.
Perhaps this is an indication for us to abandon python (which is properly a fair prototyping language) in favor of something faster to run as well as to code - and perhaps even more porable. (Example: scala which is interoperable with java or go ). We shouldn't be wasting time worrying about whether some innocuous change will slowdown the code 10x. I will start looking at alternatives.
cc @karthikraman
https://github.com/sanskrit-coders/sanskrit_data/commit/c30e35fd517bf026f01cef6e66eefe7da1a85117 and https://github.com/sanskrit-coders/jyotisha/commit/2d46b3a46d24c8e36caf0e29553d0c7fce08fdae fix the problem!
Thanks to @shreevatsa for triggering this correction.
20s runtime now!
PASSED [100%]timebudget report...
update_festival_details: 5579.41ms for 2 calls
assign_festivals_from_rules: 3268.12ms for 2 calls
compute_angas: 6344.11ms for 1 calls
assign_festival: 0.01ms for 500780 calls
get_sunrise_day_anga_spans: 2.45ms for 1910 calls
find: 7.14ms for 89 calls
set_rule_dicts: 575.89ms for 1 calls
dump_to_file: 419.12ms for 1 calls
assign_festival_numbers: 1.90ms for 2 calls
timebudget report...
Loading the file: 826.86ms for 1 calls
Was typing the following:
For what it's worth, though I couldn't get the tests to pass, I do see a slowdown in how long the test takes to fail at f0ae814
(about 30 seconds, versus 9.x seconds at previous commit). The minimal diff is this line: line 85 Removing that if
block or even replacing that self.names_dict = NAMES[key]
with self.names_dict = {}
makes the difference go away.
I don't understand the rest of the code enough to know why, but my guess is that as this makes the AngaType
object larger (about 6 times larger, 48 v/s 48+232), that causes something else to become slower.
BTW, in either case, most of the time of the test goes in sanskrit_data
module. Some of the results from pprofile -m pytest -- -k "test_panchanga_chennai_18"
(may not be the best choice of profiler; it has about 50x overhead and prints a lot of output):
At f0ae814
:
File: /usr/local/lib/python3.8/site-packages/sanskrit_data-0.6.5-py3.8.egg/sanskrit_data/collection_helper.py
File duration: 738.809s (61.24%)
--
File: /usr/local/lib/python3.8/site-packages/sanskrit_data-0.6.5-py3.8.egg/sanskrit_data/schema/common.py
File duration: 368.833s (30.57%)
--
File: /Users/shreevatsa/code/jyotisha/jyotisha/panchaanga/temporal/body.py
File duration: 10.8639s (0.90%)
--
versus (without that NAMES[key]
):
File: /usr/local/lib/python3.8/site-packages/sanskrit_data-0.6.5-py3.8.egg/sanskrit_data/collection_helper.py
File duration: 53.3035s (31.56%)
--
File: /usr/local/lib/python3.8/site-packages/sanskrit_data-0.6.5-py3.8.egg/sanskrit_data/schema/common.py
File duration: 25.2035s (14.92%)
--
File: /Users/shreevatsa/code/jyotisha/jyotisha/panchaanga/temporal/body.py
File duration: 9.47646s (5.61%)
--
The fix also clears up the angaobj branch.
@shreevatsa 's very pertinent observation: "If I'm reading the image correctly, it says that isinstance
took 16791 milliseconds in total, over 200882348 calls to it, so that's about 84 nanoseconds per call. I think that's reasonable (for Python anyway); probably the right conclusion is not that isinstance
is slow but that it's being called too many times -- then one would have to see why (maybe in some places we can proceed under the assumption that we have the right type, or move the check to a caller where it will be called fewer times), etc. Many things in Python are indeed relatively slow, but often the slowness comes from the fact that Python makes certain things too easy and the straightforward way of writing code can end up with a lot of indirection, and become slow that way. "
An experiment in this vein:
try:
return self.index == other.index
except AttributeError:
return self.index == other
Time taken: 35sec.
timebudget report...
compute_angas: 20228.54ms for 1 calls
update_festival_details: 5194.24ms for 2 calls
assign_festivals_from_rules: 2782.45ms for 2 calls
assign_festival: 0.01ms for 500780 calls
assign_tithi_yoga_nakshatra_fest: 0.06ms for 43848 calls
__eq__: 0.00ms for 943794 calls
dump_to_file: 622.63ms for 1 calls
set_rule_dicts: 578.62ms for 1 calls
__sub__: 0.00ms for 78473 calls
__add__: 0.00ms for 59969 calls
__gt__: 0.00ms for 5095 calls
timebudget report...
Loading the file: 863.30ms for 1 calls
with:
if isinstance(other, Number):
return self.index == other
return self.index == other.index
Time taken: 34sec.
FAILED [100%]timebudget report...
compute_angas: 19913.68ms for 1 calls
update_festival_details: 5101.91ms for 2 calls
assign_festivals_from_rules: 2753.11ms for 2 calls
assign_festival: 0.01ms for 500780 calls
assign_tithi_yoga_nakshatra_fest: 0.06ms for 43848 calls
__eq__: 0.00ms for 943794 calls
dump_to_file: 633.30ms for 1 calls
set_rule_dicts: 513.55ms for 1 calls
__sub__: 0.00ms for 78473 calls
__add__: 0.00ms for 59969 calls
__gt__: 0.00ms for 5095 calls
timebudget report...
Loading the file: 856.03ms for 1 calls
Also the above shows that having anga objects increases time for anga computation from 6s to 20s. Will drop that idea.
Also the above shows that having anga objects increases time for anga computation from 6s to 20s. Will drop that idea.
Retracted considering https://github.com/sanskrit-coders/jyotisha/blob/6fb654442b745c0967f566e9702d52826b1ca9a6/tests/spatio_temporal/data/timing_snapshot_vvasuki.md vs https://github.com/sanskrit-coders/jyotisha/blob/master/tests/spatio_temporal/data/timing_snapshot_vvasuki.md . Inefficient daily anga span finding was the culprit.
Defining anga objects and specifying their algebra/ arithmetic would make things simpler - but would it be slower?
Command line in all of the below
pytest -k test_panchanga_chennai_18 --log-cli-level 0
For the anga obj branch:
Takes 2 min 53 seconds = 173 seconds.
Master branch for comparison:
Time taken without timebudget use : 21.x seconds, with timebudget: 23.x seconds