473,385 Members | 1,324 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Warnings killing my performance

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.

--
Ben Sizer
Jul 18 '05 #1
10 2177

Ben> So I have these problems: warnings are slow (even when disabled),
Ben> sometimes warnings are being issued and I never see them, and given
Ben> that I never see the warnings I don't know how to get around them.

Ben> So, my first question is to ask if there is a more efficient way of
Ben> disabling warnings?

This may seem silly, but switching to the CVS version of Python (aka 2.4a0)
should help immensely, simply because that is gone:

% python2.3 ~/local/bin/timeit.py -s 'import sys ; sys.path.append("/Users/skip/tmp"); from warn import IntToRandFloat' 'IntToRandFloat(789221)'
/Users/skip/tmp/warn.py:4: FutureWarning: x<<y losing bits or changing sign will return a long in Python 2.4 and up
x = int(x << 13) ^ x
10000 loops, best of 3: 114 usec per loop
% python2.4 ~/local/bin/timeit.py -s 'import sys ; sys.path.append("/Users/skip/tmp"); from warn import IntToRandFloat' 'IntToRandFloat(789221)'
100000 loops, best of 3: 16.7 usec per loop

Ben> Lastly, a suggestion; if 2.4 will introduce an automatic promotion
Ben> to a long as a result of this shift operation, will the standard
Ben> library provide a C implementation of the lossy shift operator for
Ben> those of us that would benefit from a quick version? I'm guessing
Ben> that promoting it to a long and then getting it back to a normal
Ben> int is not exactly the speediest operation.

Apparently it's quite a bit faster than navigating all the warning
machinery. ;-)

Skip
Jul 18 '05 #2
The 'or' in "x = int(x | 0xFFFF)" was obviously meant to be an 'and',
before anybody chooses to point it out. :)

--
Kylotan
Jul 18 '05 #3

"Kylotan" <ky*****@hotmail.com> wrote in message
news:15*************************@posting.google.co m...
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?


Have you tried masking off the upper 13 bits *before* the shift? So that
there is no overflow to warn about? Does this make any sense?

TJR


Jul 18 '05 #4
"Terry Reedy" <tj*****@udel.edu> wrote in message news:<ma***************************************@py thon.org>...
"Kylotan" <ky*****@hotmail.com> wrote in message
news:15*************************@posting.google.co m...
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?


Have you tried masking off the upper 13 bits *before* the shift? So that
there is no overflow to warn about? Does this make any sense?


Yes, it makes perfect sense... but unfortunately getting rid of that
specific warning isn't enough. As noted in my first post, something is
going through the warnings mechanism silently. I changed the code to
this:

def IntToRandFloat(x):
"""Given a 32-bit integer, return a float in [-1.0, 1.0]"""
x = int(x) & 0x3FFFF # Preserve lowest 18 bits, to remove
overflow.
x = int(x << 13) ^ x # Shift left 13 bits.
return (1.0-((x*(x*x*15731+789221)+1376312589)&0x7fffffff)/1073741824.0)

And the profiler is still showing a call to warn() and warn_explicit()
for each call to IntToRandFloat. I'm also having to preserve 18 bits
instead of the desired 19 because the warning displays when I use 18,
presumably because it includes the sign bit. However now I think I am
damaging the distribution of the function (which is supposed to
generate deterministic noise).

I probably should have mentioned earlier that I'm using "Python 2.3.3
(#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)] on win32" for
what it's worth.

If I knew what warning it was, maybe I could turn it into an error to
find out what's causing it. But right now, it's a silent warning that
I can't do much about. And which is slowing down my code a lot!

I'm starting to think that I might need to write a 1-function C++
extension here, which would be a shame.

--
Ben Sizer
Jul 18 '05 #5
Kylotan wrote:
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?


Have you tried brute force?

....> timeit.py -s"import profwarn" "profwarn.IntToRandFloat(99)"
10000 loops, best of 3: 27.3 usec per loop

....> timeit.py -s"import profwarn;profwarn.disableWarnings()"
"profwarn.IntToRandFloat(99)"
100000 loops, best of 3: 7.8 usec per loop

with IntToRandFloat() copied* from your post and the following to entirely
disable warnings:

def disableWarnings():
def _theevilunwarner(*args):
pass
import warnings
warnings.warn = _theevilunwarner
warnings.warn_explicit = _theevilunwarner

I think the last line isn't necessary, but it won't do any (additional)
harm.

Peter

(*) Your email client seems to replace normal space with evil lookalikes, so
I had to delete and reinsert the entire whitespace.
Jul 18 '05 #6
On Sat, Feb 07, 2004 at 04:45:12AM -0800, Kylotan wrote:
specific warning isn't enough. As noted in my first post, something is
going through the warnings mechanism silently. I changed the code to


Have you tried "python -Wall"? It shows PendingDeprecationWarnings, which
are usually not displayed.

-Andrew.
Jul 18 '05 #7
In article <15*************************@posting.google.com> ,
ky*****@hotmail.com (Kylotan) wrote:
"Terry Reedy" <tj*****@udel.edu> wrote in message news:<ma***************************************@py thon.org>...
"Kylotan" <ky*****@hotmail.com> wrote in message
news:15*************************@posting.google.co m...
> 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?


Have you tried masking off the upper 13 bits *before* the shift? So that
there is no overflow to warn about? Does this make any sense?


Yes, it makes perfect sense... but unfortunately getting rid of that
specific warning isn't enough. As noted in my first post, something is
going through the warnings mechanism silently. I changed the code to
this:

def IntToRandFloat(x):
"""Given a 32-bit integer, return a float in [-1.0, 1.0]"""
x = int(x) & 0x3FFFF # Preserve lowest 18 bits, to remove
overflow.
x = int(x << 13) ^ x # Shift left 13 bits.
return (1.0-((x*(x*x*15731+789221)+1376312589)&0x7fffffff)/1073741824.0)

And the profiler is still showing a call to warn() and warn_explicit()
for each call to IntToRandFloat. I'm also having to preserve 18 bits
instead of the desired 19 because the warning displays when I use 18,
presumably because it includes the sign bit. However now I think I am
damaging the distribution of the function (which is supposed to
generate deterministic noise).


I notice that you're effectively cubing x, so you could
only keep 10 bits of it and be sure of avoiding 32-bit
overflow. Maybe a linear pseudo-random formula would save
some trouble. But it appears that random.randint also
generates invisible warnings.

The warnings go away with
x = long(x << 13) ^ x
Regards. Mel.
Jul 18 '05 #8
Peter Otten <__*******@web.de> wrote in message news:<c0*************@news.t-online.com>...
def disableWarnings():
def _theevilunwarner(*args):
pass
import warnings
warnings.warn = _theevilunwarner
warnings.warn_explicit = _theevilunwarner
Heh, that's great. However, I don't think it really scales well to a
full application, does it? :)
(*) Your email client seems to replace normal space with evil lookalikes, so
I had to delete and reinsert the entire whitespace.


I'm posting through Google Groups; my ISP doesn't carry more than the
last 6 threads of comp.lang.python, or indeed many other newsgroups. I
have no idea why.

--
Ben Sizer
Jul 18 '05 #9
mw*****@the-wire.com (Mel Wilson) wrote in message news:<cFQJAls/Kb*******@the-wire.com>...
I notice that you're effectively cubing x, so you could
only keep 10 bits of it and be sure of avoiding 32-bit
overflow.
I'm not sure why you say that. If I feed '10' into the formula in
question I'll get something much larger than 1000 out!
Maybe a linear pseudo-random formula would save
some trouble. But it appears that random.randint also
generates invisible warnings.
Well, I changed the whole function to the following:

rnd.seed(x)
return rnd.uniform(-1.0, 1.0)

Where rnd is an instance of Random(). This is a little quicker, and
doesn't throw any warnings (visible or otherwise). I just have to hope
the random.uniform implementation doesn't change any time soon.

I would also hope that someone will find a way to remove that hidden
warning from randint because it seems to be an unnecessary performance
hit on what is otherwise a fairly fundamental function.
The warnings go away with
x = long(x << 13) ^ x


So do the results I'm trying to get ;)

--
Ben Sizer
Jul 18 '05 #10
Kylotan wrote:
Peter Otten <__*******@web.de> wrote in message
news:<c0*************@news.t-online.com>...
def disableWarnings():
def _theevilunwarner(*args):
pass
import warnings
warnings.warn = _theevilunwarner
warnings.warn_explicit = _theevilunwarner


Heh, that's great. However, I don't think it really scales well to a
full application, does it? :)


Well, you could disable warnings in critical parts only, but that wouldn't
play well with threads. Enter the not so evil unwarner:

def disableWarnings():
originalWarn = warnings.warn
disabled = sets.Set([
id(exceptions.OverflowWarning),
id(exceptions.FutureWarning)])

def _thenotsoevilunwarner(message, category=None, stacklevel=1):
if id(category) in disabled:
#print "DISMISS", message, category
pass
else:
#print "PROPAGATE", message, category
originalWarn(message, category, stacklevel)
warnings.warn = _thenotsoevilunwarner

It's still pretty fast (10.8 vs 27.1 usec on my machine), but the duplicate
test will slow down warnings that are actually propagated.

And if you are really ambitious, you could devise a patch to speed up warn()
in the library, maybe using a similar technique as shown above.

Peter

Jul 18 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Colin Steadman | last post by:
I have created a function to kill all session variables that aren't in a safe list. This is the function - Sub PurgeSessionVariables For Each Item In Session.Contents Select Case Trim(Item)...
4
by: esmith2112 | last post by:
We replaced an aging system with a newer (faster 4-way) and presumably better system. Perfomance for most queries has improved as one would expect. However, we're getting slaughtered on performance...
4
by: PMB | last post by:
Thank you in advance for any and all assistance. I'm running Queries for updating my forms and I want to turn off the Internal Warnings that access gives. How do I do that? Michael
11
by: Michael B Allen | last post by:
Is there a standard method for supressing warnings regarding unused parameters? I have a function that might be called hundreds of thousands of times that looks like this: const void *...
39
by: clintonG | last post by:
This is not about starting a fight but an observation that seems to be proving itself on its own merit and is therefore simply a point of conjecture. I did not get serious about writing software...
2
by: dbuchanan | last post by:
I built a simple Data Access Layer with the Visual Studio 2005 DataSet Designer using the wizard. All who I have talked to who use it, articles I haver read by those who use it speak very highly...
6
by: laststubborn | last post by:
Hi everybody, We have a very large database and high transaction volume. Time to time these transactions are locking each other and decrease the performance of the database. Is there any way...
82
by: robert bristow-johnson | last post by:
here is a post i put out (using Google Groups) that got dropped by google: i am using gcc as so: $ gcc -v Using built-in specs. Target: i386-redhat-linux Configured with: ../configure...
3
by: =?Utf-8?B?Y2FzaGRlc2ttYWM=?= | last post by:
Hi, I have built an application containing a few projects (nothing that I have written)and there are a few compiler warnings (obsolete methods and the like). Does anyone know if these obsolete...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.