Ticket #10314 (closed enhancement: fixed)

Opened 2 years ago

Last modified 17 months ago

speed up comparison of Integers and native Python numeric types

Reported by: roed Owned by: AlexGhitza
Priority: major Milestone: sage-4.6.2
Component: basic arithmetic Keywords:
Cc: Work issues:
Report Upstream: N/A Reviewers: Aly Deines
Authors: David Roe Merged in: sage-4.6.2.alpha1
Dependencies: Stopgaps:

Description

Following the discussion at  http://groups.google.com/group/sage-devel/browse_thread/thread/631cd4e0a927d793?pli=1, it seemed like a good idea to speed up comparisons of integers with ints, because this often arises when using the preparser. I also added shortcuts for python longs and floats because it seemed like a good idea.

Attachments

10314.patch Download (2.7 KB) - added by roed 2 years ago.
10314.2.patch Download (4.4 KB) - added by roed 2 years ago.
updated based on referee comments; apply instead of previous patch
10314.3.patch Download (5.1 KB) - added by roed 2 years ago.
Apply instead of previous patches: fixes doctest

Change History

Changed 2 years ago by roed

comment:1 Changed 2 years ago by roed

  • Status changed from new to needs_review

comment:2 Changed 2 years ago by was

  • Status changed from needs_review to needs_work

Here's a major bug this introduces:

        822	            elif PyFloat_CheckExact(left): 
 	823	                c = -mpz_cmp_d((<Integer>right).value, PyFloat_AsDouble(right))

Note that you're comparing right to itself.

Another thought I had is that the tmp mpz could be put at the module scope and never mpz_clear'd. This means a tiny leak, but it removes the mpz_init and mpz_clear completely, and replaces them with a single mpz_set, which could be a big savings in time, since memory allocation is so expensive.

In fact, looking in integer.pyx I see this near the top:

cdef mpz_t mpz_tmp
mpz_init(mpz_tmp)

so just use that mpz_tmp that is sitting there, instead of making another one.

comment:3 Changed 2 years ago by roed

Thanks for catching that. I don't know why my test -1.5r < 3 didn't crash horribly...

I've switched to using the mpz_tmp as you suggested.

On adding some more tests, I've discovered that this patch changes the behavior of comparison of large floats to sage integers. Now we have

sage: 1000000000000000000000000000000000000000000000000000.0r==1000000000000000000000000000000000000000000000000000
False

whereas it was True before. Of course, before

sage: 1000000000000000000000000000000000000000000000000000.1r==1000000000000000000000000000000000000000000000000000
True

I think it's still worth using mpz_cmp_d because of the speed benefit; users should know to be careful with these kinds of floating point comparisons. Do you agree?

Changed 2 years ago by roed

updated based on referee comments; apply instead of previous patch

comment:4 Changed 2 years ago by roed

  • Status changed from needs_work to needs_review

comment:5 Changed 2 years ago by aly.deines

  • Status changed from needs_review to needs_work

When checking the doc tests I got the following failure:

sage -t "devel/sage/sage/rings/integer.pyx" File "/Applications/sage/sage-4.5.3/devel/sage/sage/rings/integer.pyx", line 410:

sage: TestSuite?(n).run()

Expected:

Failure in _test_pickling: Traceback (most recent call last): ... AssertionError?: 3 != 3 ------------------------------------------------------------ The following tests failed: _test_pickling

Got nothing 1 items had failures:

1 of 10 in main.example_7

*Test Failed* 1 failures. For whitespace errors, see the file /Users/aly/.sagetmp/.doctest_integer.py

[6.0 s]


The following tests failed:

sage -t "devel/sage/sage/rings/integer.pyx"

Total time for all tests: 6.0 seconds

comment:6 Changed 2 years ago by aly.deines

  • Reviewers set to Aly Deines

Changed 2 years ago by roed

Apply instead of previous patches: fixes doctest

comment:7 Changed 2 years ago by roed

  • Status changed from needs_work to needs_review

Apply 10314.3.patch

This fixes the doctest, which shows that pickling integers works better now. :-)

comment:8 Changed 2 years ago by aly.deines

  • Status changed from needs_review to positive_review

Great! Looks good.

comment:9 Changed 2 years ago by jdemeyer

  • Milestone changed from sage-4.6.1 to sage-4.6.2

comment:10 Changed 2 years ago by jdemeyer

  • Status changed from positive_review to closed
  • Resolution set to fixed
  • Merged in set to sage-4.6.2.alpha1

comment:11 Changed 17 months ago by was

It turns out that the line I flagged above as introducing a major bug, which roed fixed, in fact introduces an easy 1-liner way to segfault Sage:

sage: float('nan') > 1
Program received signal SIGFPE, Arithmetic exception.
BOOM

See #12149.

Note: See TracTickets for help on using tickets.