Ticket #10314 (closed enhancement: fixed)
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
Change History
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
-
attachment
10314.2.patch
added
updated based on referee comments; apply instead of previous patch
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
Changed 2 years ago by roed
-
attachment
10314.3.patch
added
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: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.
