473,699 Members | 2,615 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Should I use "if" or "try" (as a matter of speed)?

I know that this topic has the potential for blowing up in my face,
but I can't help asking. I've been using Python since 1.5.1, so I'm
not what you'd call a "n00b". I dutifully evangelize on the goodness
of Python whenever I talk with fellow developers, but I always hit a
snag when it comes to discussing the finer points of the execution
model (specifically, exceptions).

Without fail, when I start talking with some of the "old-timers"
(people who have written code in ADA or Fortran), I hear the same
arguments that using "if" is "better" than using "try". I think that
the argument goes something like, "When you set up a 'try' block, you
have to set up a lot of extra machinery than is necessary just
executing a simple conditional."

I was wondering how true this holds for Python, where exceptions are
such an integral part of the execution model. It seems to me, that if
I'm executing a loop over a bunch of items, and I expect some
condition to hold for a majority of the cases, then a "try" block
would be in order, since I could eliminate a bunch of potentially
costly comparisons for each item. But in cases where I'm only trying
a single getattr (for example), using "if" might be a cheaper way to
go.

What do I mean by "cheaper"? I'm basically talking about the number
of instructions that are necessary to set up and execute a try block
as opposed to an if block.

Could you please tell me if I'm even remotely close to understanding
this correctly?
--
Steve Juranich
Tucson, AZ
USA
Jul 21 '05 #1
40 3028
ncf
Honestly, I'm rather new to python, but my best bet would be to create
some test code and time it.

Jul 21 '05 #2
My shot would be to test it like this on your platform like this:

#!/usr/bin/env python
import datetime, time
t1 = datetime.dateti me.now()
for i in [str(x) for x in range(100)]:
if int(i) == i:
i + 1
t2 = datetime.dateti me.now()
print t2 - t1
for i in [str(x) for x in range(100)]:
try:
int(i) +1
except:
pass
t3 = datetime.dateti me.now()
print t3 - t2

for me (on python 2.4.1 on Linux on a AMD Sempron 2200+) it gives:
0:00:00.000637
0:00:00.000823

Jul 21 '05 #3
Steve Juranich <sj******@gmail .com> wrote:
Without fail, when I start talking with some of the "old-timers"
(people who have written code in ADA or Fortran), I hear the same
arguments that using "if" is "better" than using "try".
Well, you've now got a failure. I used to write Fortran on punch cards, so
I guess that makes me an "old-timer", and I don't agree with that argument.
I think that the argument goes something like, "When you set up a 'try'
block, you have to set up a lot of extra machinery than is necessary
just executing a simple conditional."
That sounds like a very C++ kind of attitude, where efficiency is prized
above all else, and exception handling is relatively heavy-weight compared
to a simple conditional.
What do I mean by "cheaper"? I'm basically talking about the number
of instructions that are necessary to set up and execute a try block
as opposed to an if block.


Don't worry about crap like that until the whole application is done and
it's not running fast enough, and you've exhausted all efforts to identify
algorithmic improvements that could be made, and careful performance
measurements have shown that the use of try blocks is the problem.

Exceptions are better than returning an error code for several reasons:

1) They cannot be silently ignored by accident. If you don't catch an
exception, it bubbles up until something does catch it, or nothing does and
your program dies with a stack trace. You can ignore them if you want, but
you have to explicitly write some code to do that.

2) It separates the normal flow of control from the error processing. In
many cases, this makes it easier to understand the program logic.

3) In some cases, they can lead to faster code. A classic example is
counting occurances of items using a dictionary:

count = {}
for key in whatever:
try:
count[key] += 1
except KeyError:
count[key] = 1

compared to

count = {}
for key in whatever:
if count.hasKey(ke y):
count[key] += 1
else:
count[key] = 1

if most keys are going to already be in the dictionary, handling the
occasional exception will be faster than calling hasKey() for every one.
Jul 21 '05 #4
wi******@hotmai l.com <ma**********@g mail.com> wrote:
My shot would be to test it like this on your platform like this:

#!/usr/bin/env python
import datetime, time
t1 = datetime.dateti me.now()
for i in [str(x) for x in range(100)]:
if int(i) == i:
i + 1
t2 = datetime.dateti me.now()
print t2 - t1
for i in [str(x) for x in range(100)]:
try:
int(i) +1
except:
pass
t3 = datetime.dateti me.now()
print t3 - t2

for me (on python 2.4.1 on Linux on a AMD Sempron 2200+) it gives:
0:00:00.000637
0:00:00.000823


PowerBook:~/Desktop wezzy$ python test.py
0:00:00.001206
0:00:00.002092

Python 2.4.1 Pb15 with Tiger
--
Ciao
Fabio
Jul 21 '05 #5
wi******@hotmai l.com a écrit :
My shot would be to test it like this on your platform like this:

#!/usr/bin/env python
import datetime, time
Why not use the timeit module instead ?
t1 = datetime.dateti me.now()
for i in [str(x) for x in range(100)]:
A bigger range (at least 10/100x more) would probably be better...
if int(i) == i:
This will never be true, so next line...
i + 1
....wont never be executed.
t2 = datetime.dateti me.now()
print t2 - t1
for i in [str(x) for x in range(100)]:
try:
int(i) +1
except:
pass
This will never raise, so the addition will always be executed (it never
will be in the previous loop).
t3 = datetime.dateti me.now()
print t3 - t2


BTW, you end up including the time spent printing t2 - t1 in the
timing, and IO can be (very) costly.

(snip meaningless results)

The "test-before vs try-expect strategy" is almost a FAQ, and the usual
answer is that it depends on the hit/misses ratio. If the (expected)
ratio is high, try-except is better. If it's low, test-before is better.

HTH
Jul 21 '05 #6
* Steve Juranich (2005-07-09 19:21 +0100)
I know that this topic has the potential for blowing up in my face,
but I can't help asking. I've been using Python since 1.5.1, so I'm
not what you'd call a "n00b". I dutifully evangelize on the goodness
of Python whenever I talk with fellow developers, but I always hit a
snag when it comes to discussing the finer points of the execution
model (specifically, exceptions).

Without fail, when I start talking with some of the "old-timers"
(people who have written code in ADA or Fortran), I hear the same
arguments that using "if" is "better" than using "try". I think that
the argument goes something like, "When you set up a 'try' block, you
have to set up a lot of extra machinery than is necessary just
executing a simple conditional."

I was wondering how true this holds for Python, where exceptions are
such an integral part of the execution model. It seems to me, that if
I'm executing a loop over a bunch of items, and I expect some
condition to hold for a majority of the cases, then a "try" block
would be in order, since I could eliminate a bunch of potentially
costly comparisons for each item. But in cases where I'm only trying
a single getattr (for example), using "if" might be a cheaper way to
go.

What do I mean by "cheaper"? I'm basically talking about the number
of instructions that are necessary to set up and execute a try block
as opposed to an if block.


"Catch errors rather than avoiding them to avoid cluttering your code
with special cases. This idiom is called EAFP ('easier to ask
forgiveness than permission'), as opposed to LBYL ('look before you
leap')."

http://jaynes.colorado.edu/PythonIdioms.html
Jul 21 '05 #7

"wi******@hotma il.com" <ma**********@g mail.com> wrote in message
news:11******** **************@ g47g2000cwa.goo glegroups.com.. .
My shot would be to test it like this on your platform like this:

#!/usr/bin/env python
import datetime, time
t1 = datetime.dateti me.now()
for i in [str(x) for x in range(100)]:
if int(i) == i:
i + 1
t2 = datetime.dateti me.now()
print t2 - t1
for i in [str(x) for x in range(100)]:
try:
int(i) +1
except:
pass
t3 = datetime.dateti me.now()
print t3 - t2


This is not a proper test since the if condition always fails and the
addition not done while the try succeeds and the addition is done. To be
equivalent, remove the int call in the try part: try: i+1. This would
still not a proper test since catching exceptions is known to be expensive
and try: except is meant for catching *exceptional* conditions, not
always-bad conditions. Here is a test that I think more useful:

for n in [1,2,3,4,5,10,20 ,50,100]:
# time this
for i in range(n):
if i != 0: x = 1/i
else: pass
# versus
for i in range(n):
try x = 1/i
except ZeroDivisionErr or: pass

I expect this will show if faster for small n and try for large n.

Terry J. Reedy

Jul 21 '05 #8
"Thorsten Kampe" <th******@thors tenkampe.de> wrote in message
news:6i******** *************** ***@40tude.net. ..
* Steve Juranich (2005-07-09 19:21 +0100)
I know that this topic has the potential for blowing up in my face,
but I can't help asking. I've been using Python since 1.5.1, so I'm
not what you'd call a "n00b". I dutifully evangelize on the goodness
of Python whenever I talk with fellow developers, but I always hit a
snag when it comes to discussing the finer points of the execution
model (specifically, exceptions).

Without fail, when I start talking with some of the "old-timers"
(people who have written code in ADA or Fortran), I hear the same
arguments that using "if" is "better" than using "try". I think that
the argument goes something like, "When you set up a 'try' block, you
have to set up a lot of extra machinery than is necessary just
executing a simple conditional."

I was wondering how true this holds for Python, where exceptions are
such an integral part of the execution model. It seems to me, that if
I'm executing a loop over a bunch of items, and I expect some
condition to hold for a majority of the cases, then a "try" block
would be in order, since I could eliminate a bunch of potentially
costly comparisons for each item. But in cases where I'm only trying
a single getattr (for example), using "if" might be a cheaper way to
go.

What do I mean by "cheaper"? I'm basically talking about the number
of instructions that are necessary to set up and execute a try block
as opposed to an if block.


"Catch errors rather than avoiding them to avoid cluttering your code
with special cases. This idiom is called EAFP ('easier to ask
forgiveness than permission'), as opposed to LBYL ('look before you
leap')."

http://jaynes.colorado.edu/PythonIdioms.html


It depends on what you're doing, and I don't find a "one size fits all"
approach to be all that useful.

If execution speed is paramount and exceptions are relatively rare,
then the try block is the better approach.

If you simply want to throw an exception, then the clearest way
of writing it that I've ever found is to encapsulate the raise statement
together with the condition test in a subroutine with a name that
describes what's being tested for. Even a name as poor as
"HurlOnFalseCon dition(<conditi on>, <exception>, <parms>, <message>)
can be very enlightening. It gets rid of the in-line if and raise
statements,
at the cost of an extra method call.

John Roth

In both approaches, you have some
error handling code that is going to clutter up your program flow.
Jul 21 '05 #9
Steve Juranich wrote:
I was wondering how true this holds for Python, where exceptions are such
an integral part of the execution model. It seems to me, that if I'm
executing a loop over a bunch of items, and I expect some condition to
hold for a majority of the cases, then a "try" block would be in order,
since I could eliminate a bunch of potentially costly comparisons for each
item.
Exactly.
But in cases where I'm only trying a single getattr (for example),
using "if" might be a cheaper way to go.
Relying on exceptions is faster. In the Python world, this coding style
is called EAFP (easier to ask forgiveness than permission). You can try
it out, just do something 10**n times and measure the time it takes. Do
this twice, once with prior checking and once relying on exceptions.

And JFTR: the very example you chose gives you yet another choice:
getattr can take a default parameter.
What do I mean by "cheaper"? I'm basically talking about the number of
instructions that are necessary to set up and execute a try block as
opposed to an if block.


I don't know about the implementation of exceptions but I suspect most
of what try does doesn't happen at run-time at all, and things get
checked and looked for only if an exception did occur. An I suspect that
it's machine code that does that checking and looking, not byte code.
(Please correct me if I'm wrong, anyone with more insight.)

--
Thomas

Jul 21 '05 #10

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

Similar topics

4
1748
by: WindAndWaves | last post by:
Hi Gurus I am building my first ever PHP site. Should I worry about speed? These are the parameters of my site - MySQL database with about 500 records (about 50 fields each) and a couple of small related tables - about two or three visitors at the same time - hosted on fast and large server in the US
28
2593
by: Maboroshi | last post by:
Hi I am fairly new to programming but not as such that I am a total beginner From what I understand C and C++ are faster languages than Python. Is this because of Pythons ability to operate on almost any operating system? Or is there many other reasons why? I understand there is ansi/iso C and C++ and that ANSI/ISO Code will work on any system If this is the reason why, than why don't developers create specific Python Distrubutions...
58
4671
by: Jeff_Relf | last post by:
Hi Tom, You showed: << private const string PHONE_LIST = "495.1000__424.1111___(206)564-5555_1.800.325.3333"; static void Main( string args ) { foreach (string phoneNumber in Regex.Split (PHONE_LIST, "_+")) { Console.WriteLine (phoneNumber); } } Output: 495.1000
2
620
by: Paul Brown | last post by:
Thanks for various responses - my feeling is that the cost benefit ratio is now approaching the noise level asymptote, though there was at least one good point : > compressed plain-text copy of the whole thing at > <ftp://ftp.eskimo.com/u/s/scs/C-faq/faq.Z> > Apparently it's the most up-to-date version available. Well its plain text, and it is contiguous, which is a lot better than my 331 html files totalling 982kB, but up to date it...
5
9904
by: The Last Danish Pastry | last post by:
If I run this program: ======================================= using System; using System.Runtime.InteropServices; namespace QPC { class Class1 {
7
3040
by: YAZ | last post by:
Hello, I have a dll which do some number crunching. Performances (execution speed) are very important in my application. I use VC6 to compile the DLL. A friend of mine told me that in Visual studio 2003 .net optimization were enhanced and that i must gain in performance if I switch to VS 2003 or intel compiler. So I send him the project and he returned a compiled DLL with VS 2003. Result : the VS 2003 compiled Dll is slower than the VC6...
3
1207
by: sachin | last post by:
Hi Group, I have stand alone application. I want to choose a technology which can give me stabilty for 5 to 6 yrs, good runtime speed(uses internet). Should be able to use low level programming like calling APIs, performing registry level programming. I have options like VC++ VB Any .Net language
2
1629
by: Chris Ochs | last post by:
I am pretty sure I know this already, but every time you run a Pl/Perl function it is just like running a perl script as far as having to load and compile the code right? My application runs under mod perl so I'm thinking that speed is not something I would gain by putting any of the code into the database server via Pl/Perl. Chris ---------------------------(end of broadcast)---------------------------
45
2894
by: charles.lobo | last post by:
Hi, I have recently begun using templates in C++ and have found it to be quite useful. However, hearing stories of code bloat and assorted problems I decided to write a couple of small programs to check. What I expected was that there would be minor code bloat and some speed improvement when using templates. However... I wrote a basic list container (using templates), and a list container (using virtual derived classes). I also tried...
10
11741
by: Devang | last post by:
Hello, I am using php script to upload file. some times if file size is too big(1GB) it takes too much time to upload. Can someone suggest me the way to increase upload speed. thanks
0
9173
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9033
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8911
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8882
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7748
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5872
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4375
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
2345
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2009
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.