| | 304 | |
| | 305 | === Performance |
| | 306 | Throughout my project I have always kept an eye on performance. Throughout the development of my API I have refactored often and always looked for |
| | 307 | bottlenecks using cProfile. I am happy to say no major decrease in speed has happened, and the new implementation does a couple of optimizations |
| | 308 | that were not present in the old system. Said this, I prefer to not comment on performance but just to show the benchmarks. It will be the core |
| | 309 | team to decide if this is feasible or not. |
| | 310 | |
| | 311 | === Main optimization points |
| | 312 | |
| | 313 | ==== Compute inverse relation map on first access |
| | 314 | In order to find related objects, the current implementation does the following |
| | 315 | |
| | 316 | {{{ |
| | 317 | for each model in apps |
| | 318 | for each field in model |
| | 319 | if field is a related object: |
| | 320 | if field is related to self: |
| | 321 | add to related_objects |
| | 322 | }}} |
| | 323 | REF: https://github.com/django/django/blob/master/django/db/models/options.py#L488 |
| | 324 | |
| | 325 | This tends to be expensive depending on the setup, but results in a O(models * fields) complexity. We can increase performance by |
| | 326 | computing a inverse relation map on first access. This is done only **once**, not once per model |
| | 327 | |
| | 328 | REF: https://github.com/PirosB3/django/blob/soc2014_meta_refactor_upgrade_flags_get_field/django/apps/registry.py#L176 |
| | 329 | |
| | 330 | In this way we have a map of model -> [related_object, related_object, ..] and computing a hash lookup is O(1). |
| | 331 | |
| | 332 | https://github.com/PirosB3/django/blob/soc2014_meta_refactor_upgrade_flags_get_field/django/db/models/options.py#L423 |
| | 333 | |
| | 334 | Now, only 1 small loop is needed. |
| | 335 | |
| | 336 | ==== Benchmarks |
| | 337 | Here is a benchmarks table. It is benchmarking soc2014_meta_refactor_upgrade_flags_get_field (68dc11708eb2170540729b71db6bcaf4c46d6504) |
| | 338 | against django/master |
| | 339 | |
| | 340 | https://gist.github.com/PirosB3/35a9231ee0214427321d |