Ticket #5445 (closed defect: fixed)

Opened 4 years ago

Last modified 4 years ago

[with patch, positive review] coercion is very slow when new coercions are discovered

Reported by: cwitty Owned by: robertwb
Priority: major Milestone: sage-3.4
Component: coercion Keywords:
Cc: Work issues:
Report Upstream: Reviewers:
Authors: Merged in:
Dependencies: Stopgaps:

Description

Consider the following timings:

sage: timeit("polygen(QQ, name='x'+str(ZZ.random_element(2^100)))+0")
625 loops, best of 3: 888 µs per loop
sage: timeit("polygen(QQ, name='x'+str(ZZ.random_element(2^100)))+0")
625 loops, best of 3: 1.45 ms per loop
sage: timeit("polygen(QQ, name='x'+str(ZZ.random_element(2^100)))+0", number=5000)
5000 loops, best of 3: 2.18 ms per loop
sage: timeit("polygen(QQ, name='x'+str(ZZ.random_element(2^100)))+0")
125 loops, best of 3: 5.36 ms per loop

The operation of adding the Integer 0 to the polynomial keeps getting slower and slower. This is because each time, it adds to the cache of known coercions, and there's a performance bug in the cache data structure.

In particular, in coerce_dict.pyx, this code:

        if self.threshold and len(self) > len(self.buckets) * self.threshold:
            self.resize()

calls len(self), where len(self) has a slow, O(n) implementation. So adding n items to a TripleDict takes O(n2) time.

The attached patch fixes this by storing the size in the TripleDict, instead of always recomputing it.

After applying the patch, the timings above become:

sage: timeit("polygen(QQ, name='x'+str(ZZ.random_element(2^100)))+0")
625 loops, best of 3: 690 µs per loop
sage: timeit("polygen(QQ, name='x'+str(ZZ.random_element(2^100)))+0")
625 loops, best of 3: 690 µs per loop
sage: timeit("polygen(QQ, name='x'+str(ZZ.random_element(2^100)))+0", number=5000)
5000 loops, best of 3: 691 µs per loop
sage: timeit("polygen(QQ, name='x'+str(ZZ.random_element(2^100)))+0")
625 loops, best of 3: 690 µs per loop

So the operation is essentially constant time.

Attachments

coerce-dict-performance-bug.patch Download (2.5 KB) - added by cwitty 4 years ago.

Change History

Changed 4 years ago by cwitty

comment:1 Changed 4 years ago by robertwb

  • Summary changed from [with patch, needs review] coercion is very slow when new coercions are discovered to [with patch, positive review] coercion is very slow when new coercions are discovered

Nice catch.

comment:2 Changed 4 years ago by mabshoff

  • Status changed from new to closed
  • Resolution set to fixed

Merged in Sage 3.4.rc1.

Cheers,

Michael

Note: See TracTickets for help on using tickets.