Regards
Version 1
tri=pen=hex=dt=dp=dh=1
results=[]
cota = 3
while len(results)<cota:
if tri==pen==hex:
results.append(tri)
if tri<=pen and tri<=hex:
dt+=1
tri+=dt
elif pen<=hex:
dp+=3;
pen+=dp
else:
dh+=4;
hex+=dh
print results
Version 2
cota = 3
tri=pen=hex=dt=dp=dh=1
results=[]
n=0
while n<cota:
if tri==pen==hex:
results.append(tri)
n+=1
if tri<=pen and tri<=hex:
dt+=1
tri+=dt
elif pen<=hex:
dp+=3;
pen+=dp
else:
dh+=4;
hex+=dh
print results
The following code is faster than either of your versions. Note that
'3r' is an int, whereas '3' is an Integer.
tri=pen=hex=dt=dp=dh=1r
results=[]
cota = 3r
while len(results)<cota:
if tri==pen==hex:
results.append(tri)
if tri<=pen and tri<=hex:
dt+=1r
tri+=dt
elif pen<=hex:
dp+=3r
pen+=dp
else:
dh+=4r
hex+=dh
print results
> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to sage-devel+...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org
>
In Pablo's second version there is no conversion, but still two Sage
integers are being compared.
In Tom's version the variable cota is a python int so (since taking
len() really is negligible!) the speedup comes from the speed of
comparing two (very small) python ints.
There is a lesson to be learned here, which is in fact very similar to
one which William explained very well recently: beware the Sage
preprocessor which converts every integer it sees to an Integer, which
can have serious performance consequences and is often not necessary!
John
Yep. Since this is such a common case, I wonder if we should modify
the Sage integer __richcmp__ method to be more sophisticated, and
allow direct comparisons with builtin Python types, without first
requiring them to be converted to Sage integers? The main problem
with:
"while len(results)<cota:"
is that in every iteration, len(results) is converted to a Sage
integer, and that conversion is expensive.
GMP has a function:
mpz_cmp_si
and we could rewrite Sage integers so if comparing with a Python int,
one grabs the long out of it (very quick) and calls mpz_cmp_si.
Does anybody want to do this? See the function
def __richcmp__(left, right, int op):
in devel/sage/rings/integer.pyx to get going.
> In Pablo's second version there is no conversion, but still two Sage
> integers are being compared.
>
> In Tom's version the variable cota is a python int so (since taking
> len() really is negligible!) the speedup comes from the speed of
> comparing two (very small) python ints.
>
> There is a lesson to be learned here, which is in fact very similar to
> one which William explained very well recently: beware the Sage
> preprocessor which converts every integer it sees to an Integer, which
> can have serious performance consequences and is often not necessary!
But also a good way to point out ideas for optimizations to Sage.
William
--
William Stein
Professor of Mathematics
University of Washington
http://wstein.org
> There is a lesson to be learned here, which is in fact very similar to
> one which William explained very well recently: beware the Sage
> preprocessor which converts every integer it sees to an Integer, which
> can have serious performance consequences and is often not necessary!
I've often been quite frustrated by this aspect of the preparser. Not
only does it frequently have speed issues, even for trivial things like
comparing an Integer to the length of a sequence, it also can cause
problems when calling functions from other libraries which expect a
python int and can't handle getting an Integer. Moreover, it is so
transparent most of the time that it is a surprise to beginners and
sometimes even to people who aren't so new.
What would be the consequence of having sage use python int's by
default? Could sage do the conversion to Integer just when needed?
And when is it needed? Is it just for speeding up arithmetic with
large integers, or is it also to help with the coercion framework?
Or is the main reason so that 1/2 works?
I know this has been discussed before, but I think it's worth thinking
again about whether defaulting to python int's might be better.
Dan
Yep. Since this is such a common case, I wonder if we should modify
the Sage integer __richcmp__ method to be more sophisticated, and
allow direct comparisons with builtin Python types, without first
requiring them to be converted to Sage integers?
--
Also, please _do_ report any issues with speed, external libraries,
etc., that come up.
As you can see above with ticket
http://trac.sagemath.org/sage_trac/ticket/10314 we do care, and will
try to address them!
Regarding loading scripts from the command line and get preparsing, I do either:
sage: load foo.sage
or
sage: attach foo.sage
The nice thing about attach is the file gets auto-reloaded any time it changes.
You can also load python files, e.g., "load foo.py" or "attach
foo.py", and the file won't be preparsed.
-- William
--
Yes. Without it, it is far to easy to type something like
x^3 + 2*x^2 - 1/2*x + 5/3
and having that give x^3 + 2*x^2 + 1 would be a total disaster.
However, even with Python 3, the situation won't be much better, due
to 2/3 giving 0.666666... (and this isn't customizable).
William
--
See my review. I found a major bug, and have a little idea for an
easy speedup.
This is a great example of the review process in action, by the way.
>
> BEFORE:
> sage: a = 3
> sage: b = 4r
> sage: timeit("a < b")
> 625 loops, best of 3: 1.34 µs per loop
>
> AFTER:
> sage: a = 3
> sage: b = 4r
> sage: timeit("a < b")
> 625 loops, best of 3: 147 ns per loop
>
> David
>