K
Kylotan
I have the following code:
def IntToRandFloat(x):
"""Given a 32-bit integer, return a float in [-1.0, 1.0]"""
x = int(x)
x = int(x << 13) ^ x
return (1.0-((x*(x*x*15731+789221)+1376312589)&0x7fffffff)/1073741824.0)
Basically it's a function directly copied from a C implementation. Now
it appears that the line with the left-shift causes the "losing bits
or changing sign will return a long in Python 2.4 and up" warning. All
well and good - I explicitly cast it back to an int so that the code
won't break when I upgrade Python. I also disable the warning using
warnings.filterwarnings(action = 'ignore', etc).
However when the time comes to profile my app, I see lines like these:
11266617 function calls in 488.717 CPU seconds
ncalls tottime percall cumtime percall
filename:lineno(function)
3145728 129.744 0.000 364.845 0.000
terraingen.py:22(IntToRandFloat)
3142872 150.484 0.000 235.101 0.000 warnings.py:24(warn)
3142872 84.617 0.000 84.617 0.000
warnings.py:59(warn_explicit)
Now I obviously can't afford to have almost half my program time
consumed by warnings that I don't want to see.
It gets stranger. If I change the shift line to this:
x = int(x * (2 ** 13)) ^ x
x = int(x | 0xFFFF)
....it's still calling 'warn' once for each time IntToRandFloat is
called, but I see no warning appear, even when I don't import warnings
and disable any. I have no other imports (that i can see) which might
be disabling a warning behind the scenes.
So I have these problems: warnings are slow (even when disabled),
sometimes warnings are being issued and I never see them, and given
that I never see the warnings I don't know how to get around them.
So, my first question is to ask if there is a more efficient way of
disabling warnings?
And my second is, is there a quick way of taking an integer, shifting
it left 13 bits (or multiplying by 2 ** 13, whatever), discarding any
excess bits, and which won't cause a warning?
Lastly, a suggestion; if 2.4 will introduce an automatic promotion to
a long as a result of this shift operation, will the standard library
provide a C implementation of the lossy shift operator for those of us
that would benefit from a quick version? I'm guessing that promoting
it to a long and then getting it back to a normal int is not exactly
the speediest operation.
def IntToRandFloat(x):
"""Given a 32-bit integer, return a float in [-1.0, 1.0]"""
x = int(x)
x = int(x << 13) ^ x
return (1.0-((x*(x*x*15731+789221)+1376312589)&0x7fffffff)/1073741824.0)
Basically it's a function directly copied from a C implementation. Now
it appears that the line with the left-shift causes the "losing bits
or changing sign will return a long in Python 2.4 and up" warning. All
well and good - I explicitly cast it back to an int so that the code
won't break when I upgrade Python. I also disable the warning using
warnings.filterwarnings(action = 'ignore', etc).
However when the time comes to profile my app, I see lines like these:
11266617 function calls in 488.717 CPU seconds
ncalls tottime percall cumtime percall
filename:lineno(function)
3145728 129.744 0.000 364.845 0.000
terraingen.py:22(IntToRandFloat)
3142872 150.484 0.000 235.101 0.000 warnings.py:24(warn)
3142872 84.617 0.000 84.617 0.000
warnings.py:59(warn_explicit)
Now I obviously can't afford to have almost half my program time
consumed by warnings that I don't want to see.
It gets stranger. If I change the shift line to this:
x = int(x * (2 ** 13)) ^ x
x = int(x | 0xFFFF)
....it's still calling 'warn' once for each time IntToRandFloat is
called, but I see no warning appear, even when I don't import warnings
and disable any. I have no other imports (that i can see) which might
be disabling a warning behind the scenes.
So I have these problems: warnings are slow (even when disabled),
sometimes warnings are being issued and I never see them, and given
that I never see the warnings I don't know how to get around them.
So, my first question is to ask if there is a more efficient way of
disabling warnings?
And my second is, is there a quick way of taking an integer, shifting
it left 13 bits (or multiplying by 2 ** 13, whatever), discarding any
excess bits, and which won't cause a warning?
Lastly, a suggestion; if 2.4 will introduce an automatic promotion to
a long as a result of this shift operation, will the standard library
provide a C implementation of the lossy shift operator for those of us
that would benefit from a quick version? I'm guessing that promoting
it to a long and then getting it back to a normal int is not exactly
the speediest operation.