Accessing settings.FOO in hot spots cause performance problems
|Reported by:||akaariai||Owned by:|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||yes|
Trying to access settings.FOO (no matter if it exists or not) will cause performance problems if used in hot spots of code. The reason is that settings is actually LazyObject, and each access goes through getattr. The problem is well illustrated in ticket #14290, where performance is increased considerably if a setting is cached in a global attribute.
I am trying to fix this by refactoring LazySettings in the following way: Make the new LazySettings be a regular Python object, but with a special getattr method: When first accessed, it will set up the settings in the objects own dict. After this, each access to settings.FOO, where FOO exists, will not use getattr. When trying to access settings.BAR, where BAR does not exist, the access will still need to go through getattr. This should not be a performance problem, though.
The performance increase on my laptop (using the test from #14290, with USE_L10N = False) is from 1.1 to 0.8 seconds, or 0.3 seconds. This is the cost of accessing settings.USE_L10N 60000 times and settings.USE_I18N 10000 times, plus fifteen other accesses. (The test is the http://localhost:8000/test/10000?timing one).
Attached patch passes all tests (I know how to run).
Change History (12)
Changed 5 years ago by akaariai
comment:1 Changed 5 years ago by jezdez
- Needs documentation unset
- Needs tests unset
- Patch needs improvement set
- Triage Stage changed from Unreviewed to Accepted
comment:3 Changed 5 years ago by lukeplant
- Owner changed from akaariai to lukeplant
- Status changed from new to assigned