Beware: It actually doesn't backtrack up like I thought it did. Well, theoretically it does, but it almost always stops either at the leaf node or at the sequential in practice. We are spending a lot of time in these lookups, but simple caching only buys us a small benefit. There's something else that's screwy with this code. Inefficient data access because of all the dict lookup indirection?
Expected savings for rendering courseware on large courses: ~20%, mostly from access check related code.
Profiling courseware rendering and progress display shows that we spend a lot of time crawling up the inheritance tree, looking for default values from our ancestor (InheritingFieldData.default) in a naive way. We should be able to eliminate most of these comparisons. Say we have a hierarchy that looks like:
Problem A, Problem B
Right now, both A and B are going up all the way through their ancestry, but whatever the default value is for Vertical will be the default value for that field for both A and B, so we can just cache at that layer and avoid all the extra compares. took this approach for orphan related work in (https://github.com/edx/edx-platform/pull/11095).
The modulestore is somewhat complex, so it might make sense to do this at a different layer. We already cache some inheritance related field data, so it might be better to extend that. Either way, we should avoid doing all these unnecessary compares.
Shout out to : I only thought of this because I connected some capa inline profiling results I had on hand with the blog post that you and drafted. Thanks folks!