[Python-Dev] PEP 550 v4: Decimal examples and performance (was: Re: PEP 550 v4) (original) (raw)
Yury Selivanov yselivanov.ml at gmail.com
Sat Aug 26 12:21:44 EDT 2017
- Previous message (by thread): [Python-Dev] PEP 550 v4: Decimal examples and performance (was: Re: PEP 550 v4)
- Next message (by thread): [Python-Dev] PEP 550 v4: Decimal examples and performance
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Sat, Aug 26, 2017 at 7:45 AM, Stefan Krah <stefan at bytereef.org> wrote:
Hi, thanks, on the whole this is much easier to understand.
Thanks!
I'll add some comments on the decimal examples. The thing is, decimal is already quite tricky and people do read PEPs long after they have been accepted, so they should probably reflect best practices.
Agree.
[..]
Some languages, that support coroutines or generators, recommend passing the context manually as an argument to every function, see [1] for an example. This approach, however, has limited use for Python, where there is a large ecosystem that was built to work with a TLS-like context. Furthermore, libraries like
decimal
ornumpy
rely on context implicitly in overloaded operator implementations. I'm not sure why this approach has limited use for decimal:from decimal import * def fractions(precision, x, y): ctx = Context(prec=precision) yield ctx.divide(Decimal(x), Decimal(y)) yield ctx.divide(Decimal(x), Decimal(y**2)) g1 = fractions(precision=2, x=1, y=3) g2 = fractions(precision=6, x=2, y=3) print(list(zip(g1, g2)))
Because you have to know the limitations of implicit decimal context to make this choice. Most people don't (at least from my experience).
This is the first thing I'd do when writing async-safe code.
Because you know the decimal module very well :)
Again, people do read PEPs. So if an asyncio programmer without any special knowledge of decimal reads the PEP, he probably assumes that localcontext() is currently the only option, while the safer and easy-to-reason-about context methods exist.
I agree.
Now, let's revisit the decimal precision example from the
Rationale
section, and see how the execution context can improve the situation:: import decimal decimalprec = newcontextvar() # create a new context variable # Pre-PEP 550 Decimal relies on TLS for its context. # This subclass switches the decimal context storage # to the execution context for illustration purposes. # class MyDecimal(decimal.Decimal): def init(self, value="0"): prec = decimalprec.lookup() if prec is None: raise ValueError('could not find decimal precision') context = decimal.Context(prec=prec) super().init(value, context=context) As I understand it, the example creates a context with a custom precision and attempts to use that context to create a Decimal. This doesn't switch the actual decimal context. Secondly, the precision in the context argument to the Decimal() constructor has no effect --- the context there is only used for error handling. Lastly, if the constructor did use the precision, one would have to be careful about double rounding when using MyDecimal(). I get that this is supposed to be for illustration only, but please let's be careful about what people might take away from that code.
In the next iteration of the PEP we'll remove decimal examples and replace them with something with simpler semantics. This is clearly the best choice now.
This generic caching approach is similar to what the current C implementation of
decimal
does to cache the the current decimal context, and has similar performance characteristics. I think it'll work, but can we agree on hard numbers like max 2% slowdown for the non-threaded case and 4% for applications that only use threads?
I'd be very surprised if wee see any noticeable slowdown at all. The way ContextVars will implement caching is very similar to the trick you use now.
Yury
- Previous message (by thread): [Python-Dev] PEP 550 v4: Decimal examples and performance (was: Re: PEP 550 v4)
- Next message (by thread): [Python-Dev] PEP 550 v4: Decimal examples and performance
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]