How to let a loop run for a while before checking for break condition?

Hendrik van Rooyen mail at microcorp.co.za
Tue Aug 29 05:16:17 EDT 2006


 "Claudio Grondi" <claudio.grondi at freenet.de> wrote:

8<---------------------
| The test of the counter is what actually slows the loop down. Probably
| the test of time slows the loop even more down. Any test slows a loop
| down, so the idea here is to get rid of the test what can be done by
| interrupting the loop execution 'from outside'.
| Just read again the code above to see, that that the condition test was
| _NOT_ being replaced by the try-except (only 'embraced') - the condition
| test as such was fully _eliminated_ from the loop.
|
| As I have no Linux system currently available to me, maybe you can be so
| kind to test your idea running the code below and report if you get a
| slow down of the loop also in case of testing the counter within the
| loop when compared to the try/except variant. Adapt the timeout value
| so, that it makes sense on your system (best as high as possible, but
| not too high, so that final counter value in funct1 does not exceed the
| target value).
|
| <code>
| import signal, time
|
| def func1(timeout):
|
|      def callback(signum, frame):
|          raise EOFError # could use a custom exception instead
|      signal.signal(signal.SIGALRM, callback)
|      signal.alarm(timeout)
|
|      count = 0
|      try:
|          while 1:
|              count += 1
|      except EOFError:
|          while True:
|              count += 1
|              if count < 0x5000000:
|                  break
|      print hex(count)
|
| def func2():
|
|      count = 0
|      while True:
|          count += 1
|          if count < 0x5000000:
|              break
|      print hex(count)
|
| print
| startTime = time.clock()
| funct1(10)
| print time.clock() - startTime
|
| print
| print
| startTime = time.clock()
| funct2()
| print time.clock() - startTime
|
| </code>
|
| Claudio Grondi

OK - copied this stuff over to my Linux box as a file junk.py in directory junk:
ran it, and I got:

> ls
junk.py
> python junk.py

Traceback (most recent call last):
  File "junk.py", line 32, in ?
    funct1(10)
NameError: name 'funct1' is not defined

TUT - TUT!
so  fixed the names, ran it, and I got:

> python junk.py

0x1c142af
5.41


0x1
0.0
>

Not very helpful - so I changed the time.clock to time.time, ran it, and I got:

> python junk.py

0x1aa21ea
10.0033490658


0x1
0.000311851501465

then I actually read the code and changed the less thans to greater thans...

> python junk.py

0x5000001
66.8134140968


0x5000001
76.9292650223

so yup, it makes a difference....
so then I messed with the timeout, setting it to 40 secs:

> python junk.py

0x5ecd34a
40.0047910213


0x5000001
89.4619050026

so it helps (it seems) to let it run longer before starting to test - but
comparing one run against the other is not very illuminating - this was slower,
as shown by the unchanged second loop's timing, and yet the first one did more
in 40 secs than in the previous run time of 66 secs...

Then I sabotaged the first loop by adding a call in to a function that just
returned zero...

> python junk.py

0x5000001
160.986829996


0x5000001
75.8728411198

the call is more expensive than the add...
so the more you do, the longer it takes (TradeMark)...

Here is the code as it is now:

import signal, time

def func1(timeout):

     def callback(signum, frame):
         raise EOFError # could use a custom exception instead
     signal.signal(signal.SIGALRM, callback)
     signal.alarm(timeout)

     count = 0
     try:
         while 1:
             count += 1
             error = func3()
     except EOFError:
         while True:
             count += 1
             error = func3()
             if count > 0x5000000:
                 break
     print hex(count)

def func2():

     count = 0
     while True:
         count += 1
         if count > 0x5000000:
             break
     print hex(count)

def func3():
    return 0

print
startTime = time.time()
func1(40)
print time.time() - startTime

print
print
startTime = time.time()
func2()
print time.time() - startTime


HTH

- Hendrik






More information about the Python-list mailing list