sympy / sympy_benchmarks

Some benchmarks of SymPy
14 stars 32 forks source link

add assumption benchmark of core #73

Open RituRajSingh878 opened 4 years ago

RituRajSingh878 commented 4 years ago

I have added assumption benchmarks. I will add a few more commits to the assumption bench. Then we can merge it. Also, if anything you want to modify in the code, then please tell.

oscarbenjamin commented 4 years ago

The examples you have picked mostly have precomputed cached assumptions:

In [5]: S.One._assumptions                                                                                                                     
Out[5]: 
{'commutative': True,
 'real': True,
 'imaginary': False,
 'infinite': False,
 'complex': True,
 'hermitian': True,
 'finite': True,
 'extended_real': True,
 'integer': True,
 'algebraic': True,
 'rational': True,
 'irrational': False,
 'transcendental': False,
 'noninteger': False,
 'zero': False,
 'extended_nonzero': True,
 'nonzero': True,
 'even': False,
 'odd': True,
 'extended_negative': False,
 'negative': False,
 'extended_positive': True,
 'nonpositive': False,
 'extended_nonpositive': False,
 'extended_nonnegative': True,
 'positive': True,
 'nonnegative': True}

It's reasonable to time the performance of this but I don't think we would need to do it exhaustively. It would be better to time some things that are slow or have the potential to be slow e.g.:

In [17]: x = Symbol('x', positive=True)                                                                                                        

In [18]: p = random_poly(x, 10, -10, 10)                                                                                                       

In [19]: p                                                                                                                                     
Out[19]: 
     10      9      8      7      5      4      3      2          
- 4⋅x   + 8⋅x  + 9⋅x  + 3⋅x  + 5⋅x  - 7⋅x  - 6⋅x  - 8⋅x  + 2⋅x + 1

In [20]: %time p.is_positive                                                                                                                   
CPU times: user 396 ms, sys: 1.68 ms, total: 398 ms
Wall time: 403 ms

In [21]: %time p.is_positive                                                                                                                   
CPU times: user 8 µs, sys: 0 ns, total: 8 µs
Wall time: 13.1 µs

Note that the second run of is_positive here is instantaneous because the result is cached on the instance:

In [22]: p._assumptions                                                                                                                        
Out[22]: 
{'positive': None,
 'finite': True,
 'infinite': False,
 'extended_positive': None,
 'extended_real': True,
 'commutative': True,
 'imaginary': False,
 'real': True,
 'complex': True,
 'hermitian': True,
 'extended_nonpositive': None,
 'negative': None,
 'extended_negative': None,
 'zero': None,
 'odd': None,
 'irrational': None,
 'rational': None,
 'algebraic': None,
 'integer': None,
 'extended_nonnegative': None}
RituRajSingh878 commented 4 years ago

Okay, got it. I can close this pr, or may I will keep only one benchmark from each function. But I think it is not necessary to benchmark these assumptions. So whatever suitable you can tell me.

oscarbenjamin commented 4 years ago

I think it's good to keep a small number of these benchmarks just to make sure that something like S.Zero.is_zero doesn't happen to slow down. I would make a parameterised test that tries a few different values like:


class TimeAssumptionsSingleton:

    params = ('Half', 'Infinity', 'Exp1', ...)

    def setup(self, name):
        self.singleton = getattr(S, name)

    def time_is_zero(self):
        self.singleton.is_zero

    def time_is_positive(self):
        self.singleton.is_positive
asmeurer commented 4 years ago

There's also no point to doing the is False or is True.

RituRajSingh878 commented 4 years ago

I think it's good to keep a small number of these benchmarks just to make sure that something like S.Zero.is_zero doesn't happen to slow down. I would make a parameterised test that tries a few different values like:


class TimeAssumptionsSingleton:

    params = ('Half', 'Infinity', 'Exp1', ...)

    def setup(self, name):
        self.singleton = getattr(S, name)

    def time_is_zero(self):
        self.singleton.is_zero

    def time_is_positive(self):
        self.singleton.is_positive

ok, I will try to add like this.