Opened 9 years ago
Closed 9 years ago
#25750 closed Cleanup/optimization (fixed)
During makemigrations Options._expire_cache takes 30% of the time
Reported by: | Patryk Zawadzki | Owned by: | Patryk Zawadzki |
---|---|---|---|
Component: | Migrations | Version: | 1.8 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Here's the profiler output:
215373161 function calls (214826612 primitive calls) in 282.839 seconds Ordered by: internal time List reduced from 6484 to 10 due to restriction <10> ncalls tottime percall cumtime percall filename:lineno(function) 5225318 59.334 0.000 89.667 0.000 django/db/models/options.py:711(_expire_cache) 40538898 27.751 0.000 27.751 0.000 {delattr} 16538241 18.624 0.000 38.450 0.000 django/apps/config.py:164(get_models) 485536 16.907 0.000 27.126 0.000 django/db/models/fields/__init__.py:358(deconstruct) 4466221 12.337 0.000 20.062 0.000 /usr/lib64/python2.7/collections.py:109(values) 79811 10.893 0.000 53.060 0.001 django/apps/registry.py:153(get_models) 73250 10.582 0.000 43.745 0.001 django/db/models/fields/related.py:317(swappable_setting) 495362 8.314 0.000 11.430 0.000 django/db/models/fields/__init__.py:137(__init__) 24359432 7.790 0.000 7.790 0.000 /usr/lib64/python2.7/collections.py:78(__iter__) 15623269/15397100 7.142 0.000 7.330 0.000 {getattr}
I have a pull request ready that makes it slightly better:
164872486 function calls (164325937 primitive calls) in 199.897 seconds Ordered by: internal time List reduced from 6484 to 10 due to restriction <10> ncalls tottime percall cumtime percall filename:lineno(function) 16538241 18.580 0.000 38.545 0.000 django/apps/config.py:164(get_models) 485536 16.290 0.000 26.736 0.000 django/db/models/fields/__init__.py:358(deconstruct) 4466221 12.357 0.000 20.069 0.000 /usr/lib64/python2.7/collections.py:109(values) 79811 10.933 0.000 53.182 0.001 django/apps/registry.py:153(get_models) 73250 10.694 0.000 43.931 0.001 django/db/models/fields/related.py:317(swappable_setting) 5225318 9.295 0.000 9.406 0.000 django/db/models/options.py:711(_expire_cache) 495362 8.807 0.000 11.958 0.000 django/db/models/fields/__init__.py:137(__init__) 24359432 7.777 0.000 7.777 0.000 /usr/lib64/python2.7/collections.py:78(__iter__) 15623269/15397100 7.316 0.000 7.504 0.000 {getattr} 2 4.863 2.431 4.863 2.431 {raw_input}
Change History (7)
comment:1 by , 9 years ago
Has patch: | set |
---|
comment:2 by , 9 years ago
Triage Stage: | Unreviewed → Ready for checkin |
---|
comment:3 by , 9 years ago
Triage Stage: | Ready for checkin → Accepted |
---|
Can you get a similar result using actual timing functions such as timeit
? I've looked into this before, and if my memory serves me right the results of profiling in this case are highly skewed, and the actual improvements are barely noticeable.
Another thing to keep in mind is that #24397 greatly reduces the number of calls to _expire_cache()
.
comment:4 by , 9 years ago
In my case it is noticeably faster even if the act of profiling itself skews the results by making function call more expensive. The slowest part was depending on try/except to trap nonexistent attributes. It may not make much difference in most projects but the one I work for takes several minutes to generate migrations.
comment:5 by , 9 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
It would be interesting to know why it makes such a difference in some projects, and none in others.
comment:6 by , 9 years ago
I suppose with #24397 it will make a much smaller difference. In our case according to migrate --list
there are 35 apps with 221 migrations.
Pull request: https://github.com/django/django/pull/5649