flask icon indicating copy to clipboard operation
flask copied to clipboard

Pass the request ctx rather than use the globals in the app

Open pgjones opened this issue 2 years ago • 5 comments

The globals have a performance penalty which can be justified for the convinience in user code. In the app however the ctx can easily be passed through the method calls thereby reducing the performance penalty.

This may affect extensions if they have subclassed the app and overridden these methods.

Checklist:

  • [x] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
  • [x] Add or update relevant docs, in the docs folder and in code.
  • [x] Add an entry in CHANGES.rst summarizing the change and linking to the issue.
  • [x] Add .. versionchanged:: entries in any relevant code docs.
  • [x] Run pre-commit hooks and fix any issues.
  • [x] Run pytest and tox, no tests failed.

pgjones avatar Aug 20 '23 20:08 pgjones

I've done something similar for Quart after finding it had a significant impact on micro benchmarks.

Edit: The quart study was done a few years ago before the switch to ContextVars which seem significantly quicker. I still think this is a useful change, but seems less performance motivated now.

pgjones avatar Aug 20 '23 20:08 pgjones

My initial reaction is that while this makes sense, I'm uncomfortable with making the change. I'll have to think about this for a little bit.

davidism avatar Aug 27 '23 14:08 davidism

Could you give more information about the benchmarks? How micro are we talking; how fast does the complexity of the app overshadow any speed gains?

Is the speed loss in the use of the proxy, or is the gain in the use of the local variable? Perhaps using _cv_req.get() directly and avoiding the proxy could have a similar improvement?

davidism avatar Aug 27 '23 14:08 davidism

This is an interesting one, with Quart the equivalent to this makes around a 1.5 times improvement, whereas for Flask it doesn't seem to have any affect (maybe a minor positive one). I don't think I can therefore remove it from Quart, but I'd like the APIs to match.

(I tried _cv_request in Quart and it made little difference.)

Also I don't think this makes it more complex - without knowledge of Flask's globals it would be expected to be passed via the call chain.

pgjones avatar Aug 28 '23 18:08 pgjones

This will be deferred to allow further discussion.

pgjones avatar Sep 16 '23 14:09 pgjones