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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Claudio Grondi

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


    Sometimes it is known in advance, that the time spent in a loop will be
    in order of minutes or even hours, so it makes sense to optimize each
    element in the loop to make it run faster.
    One of instructions which can sure be optimized away is the check for
    the break condition, at least within the time where it is known that the
    loop will not reach it.

    Any idea how to write such a loop?

    e.g.

    counter = 2*64

    while counter(BUT DON'T CHECK IT THE FIRST ONE HOUR LONG):
    ... do something ... # and decrease the counter

    Thanks for any hint, but in particular if related to timers on the
    Windows 2000/XP system I am mainly working with.

    What do you think about this idea? Does it make sense?

    Claudio Grondi
  • Diez B. Roggisch

    #2
    Re: How to let a loop run for a while before checking for break condition?

    Claudio Grondi schrieb:
    >
    Sometimes it is known in advance, that the time spent in a loop will be
    in order of minutes or even hours, so it makes sense to optimize each
    element in the loop to make it run faster.
    One of instructions which can sure be optimized away is the check for
    the break condition, at least within the time where it is known that the
    loop will not reach it.
    >
    Any idea how to write such a loop?
    >
    e.g.
    >
    counter = 2*64
    >
    while counter(BUT DON'T CHECK IT THE FIRST ONE HOUR LONG):
    now = time.time()
    while time.time() - now < 3600.0 or some_other_cond ition:
    ...


    The short circuiting of the or will prevent the execution of
    some_other_cond ition.
    ... do something ... # and decrease the counter
    >
    Thanks for any hint, but in particular if related to timers on the
    Windows 2000/XP system I am mainly working with.
    >
    What do you think about this idea? Does it make sense?

    What idea?

    Diez

    Comment

    • Claudio Grondi

      #3
      Re: How to let a loop run for a while before checking for break condition?

      Diez B. Roggisch wrote:
      Claudio Grondi schrieb:
      >
      >>
      >Sometimes it is known in advance, that the time spent in a loop will
      >be in order of minutes or even hours, so it makes sense to optimize
      >each element in the loop to make it run faster.
      >One of instructions which can sure be optimized away is the check for
      >the break condition, at least within the time where it is known that
      >the loop will not reach it.
      >>
      >Any idea how to write such a loop?
      >>
      >e.g.
      >>
      >counter = 2*64
      >>
      >while counter(BUT DON'T CHECK IT THE FIRST ONE HOUR LONG):
      >
      >
      now = time.time()
      while time.time() - now < 3600.0 or some_other_cond ition:
      ...
      >
      >
      The short circuiting of the or will prevent the execution of
      some_other_cond ition.
      >
      > ... do something ... # and decrease the counter
      >>
      >Thanks for any hint, but in particular if related to timers on the
      >Windows 2000/XP system I am mainly working with.
      >>
      >What do you think about this idea? Does it make sense?
      >
      What idea?
      This one you haven't probably got from what I have written.
      I thought, that the introductory text gives enough context to be able to
      see what I mean, but I was apparently wrong.

      The idea is to speed up a loop by using a timer interrupt interfering
      with the loop, so that only after the timer interrupt would occur, the
      loop will start to check its break condition in each iteration.
      No checking of any kind in the loop should happen up to that time to
      minimize the number of operations in each iteration within the loop
      itself (i.e. the loop more or less won't know, that there is a timer on
      its way to change the loops behavior at a later time).

      I hope this above helps to understand what I would like to achieve.

      Claudio Grondi

      Comment

      • Diez B. Roggisch

        #4
        Re: How to let a loop run for a while before checking for break condition?

        The idea is to speed up a loop by using a timer interrupt interfering
        with the loop, so that only after the timer interrupt would occur, the
        loop will start to check its break condition in each iteration.
        No checking of any kind in the loop should happen up to that time to
        minimize the number of operations in each iteration within the loop
        itself (i.e. the loop more or less won't know, that there is a timer on
        its way to change the loops behavior at a later time).
        A while loop has a condition. period. The only thing to change that is
        to introduce a uncoditioned loop, and use self-modifying code to make it
        a while-loop after that timer interrupt of yours.

        But of course that whole thing is a moot point - if shaving mu-secs on
        that level is needed for your application, use C or assembly instead.


        Diez

        Comment

        • Tal Einat

          #5
          Re: How to let a loop run for a while before checking for break condition?


          Diez B. Roggisch wrote:
          The idea is to speed up a loop by using a timer interrupt interfering
          with the loop, so that only after the timer interrupt would occur, the
          loop will start to check its break condition in each iteration.
          No checking of any kind in the loop should happen up to that time to
          minimize the number of operations in each iteration within the loop
          itself (i.e. the loop more or less won't know, that there is a timer on
          its way to change the loops behavior at a later time).
          >
          A while loop has a condition. period. The only thing to change that is
          to introduce a uncoditioned loop, and use self-modifying code to make it
          a while-loop after that timer interrupt of yours.
          >
          True. Still, if checking the condition is slowing down the loop,
          perhaps it could be optimized somewhat by having a timeout set a
          boolean flag, thus having the loop check a simpler condition, which may
          be faster.

          You can have a separate thread time.sleep() for as long as you want,
          and then set the flag which the loop's condition checks. This way you
          don't call time.time() on every iteration.

          Another approach could be partial loop nesting/unrolling, if the
          condition doesn't necessarily have to be checked on every iteration.
          Just have an outer loop checking the condition, and an inner loop
          (possibly unrolled) doing whatever it is your loop does, several times
          (2-1000000, optimize for your needs). This just lets you check the
          condition less often.
          But of course that whole thing is a moot point - if shaving mu-secs on
          that level is needed for your application, use C or assembly instead.
          >
          I agree, though those aren't the only alternatives - you could also try
          going "half-way" with Pyrex.

          - Tal Einat
          reduce(lambda m,x:[m[i]+s[-1] for i,s in enumerate(sorte d(m))],
          [[chr(154-ord(c)) for c in '.&-&,l.Z95193+1 79-']]*18)[3]

          Comment

          • Fredrik Lundh

            #6
            Re: How to let a loop run for a while before checking for breakcondition?

            Diez B. Roggisch wrote:
            A while loop has a condition. period. The only thing to change that is
            to introduce a uncoditioned loop, and use self-modifying code to make it
            a while-loop after that timer interrupt of yours.
            or use a timer interrupt to interrupt the loop:

            import signal, time

            def func1(timeout):

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

            count = 0
            try:
            while 1:
            count += 1
            except EOFError:
            for i in range(10):
            count += 1
            print count

            for an utterly trivial task like the one in that example, the alarm
            version runs about five times faster than a polling version, on my test
            machine (ymmv):

            def func2(timeout):

            gettime = time.time
            t_limit = gettime() + timeout

            count = 0
            while gettime() < t_limit:
            count += 1
            for i in range(10):
            count += 1
            print count

            </F>

            Comment

            • Claudio Grondi

              #7
              Re: How to let a loop run for a while before checking for break condition?

              Diez B. Roggisch wrote:
              >The idea is to speed up a loop by using a timer interrupt interfering
              >with the loop, so that only after the timer interrupt would occur, the
              >loop will start to check its break condition in each iteration.
              >No checking of any kind in the loop should happen up to that time to
              >minimize the number of operations in each iteration within the loop
              >itself (i.e. the loop more or less won't know, that there is a timer
              >on its way to change the loops behavior at a later time).
              >
              >
              A while loop has a condition. period. The only thing to change that is
              to introduce a uncoditioned loop, and use self-modifying code to make it
              a while-loop after that timer interrupt of yours.
              >
              But of course that whole thing is a moot point - if shaving mu-secs on
              that level is needed for your application, use C or assembly instead.
              Going to C or assembly addresses the speed, but does not address the
              question asked, as the problem of checking a condition in a loop remains
              the same (even if at another speed level).

              Here some more context to put more light into what I would like to know
              about:
              any program runs within an operating system and this system (and in
              particular Microsoft Windows) does many, many things beside running the
              program. The idea is to use the resources wasted in cycles of the CPU
              spent on processing the other things anyway for the program itself.
              I have only a vague draft of what I would like to achieve so please
              don't get what I write here about how I imagine it should be done too
              seriously:
              I think, that the application can start with an unconditional loop
              and tell the operating system to stop this loop and provide a response
              when e.g. one hour is over. When that happens a pre-prepared conditional
              loop will start (which was waiting to be awoken) assuming the same
              environment (values of variables will be preserved, so it is clear where
              to continue) as the previous one.

              As an intermediate quick and dirty solution for practical use there is
              the possibility to let the Python script run into an error or to break
              its run with Ctrl+C if it is apparent it is ready (e.g. the first
              approach has just saved me 20 CPU minutes of a four CPU hours needing
              script and the condition was checking only the value of an iteration
              counter so was not a very time consuming one).

              Just thought that for sure someone had already the same/similar idea and
              might share here an elegant Pythonic solution addressing this issue.

              Claudio Grondi

              Comment

              • Claudio Grondi

                #8
                Re: How to let a loop run for a while before checking for breakcondition?

                Fredrik Lundh wrote:
                Diez B. Roggisch wrote:
                >
                >A while loop has a condition. period. The only thing to change that is
                >to introduce a uncoditioned loop, and use self-modifying code to make
                >it a while-loop after that timer interrupt of yours.
                >
                >
                or use a timer interrupt to interrupt the loop:
                >
                import signal, time
                >
                def func1(timeout):
                >
                def callback(signum , frame):
                raise EOFError # could use a custom exception instead
                signal.signal(s ignal.SIGALRM, callback)
                signal.alarm(ti meout)
                >
                count = 0
                try:
                while 1:
                count += 1
                except EOFError:
                for i in range(10):
                count += 1
                print count
                >
                for an utterly trivial task like the one in that example, the alarm
                version runs about five times faster than a polling version, on my test
                machine (ymmv):
                >
                def func2(timeout):
                >
                gettime = time.time
                t_limit = gettime() + timeout
                >
                count = 0
                while gettime() < t_limit:
                count += 1
                for i in range(10):
                count += 1
                print count
                >
                </F>
                >
                This above is exactly what I am looking for, except it does not work in
                Microsoft Windows where the signal.alarm() function is not available.

                So now the only thing I would like to know is how to achieve the same
                functionality when running Python on a Microsoft Windows box.

                Claudio Grondi

                Comment

                • Diez B. Roggisch

                  #9
                  Re: How to let a loop run for a while before checking for breakcondition?

                  Fredrik Lundh schrieb:
                  Diez B. Roggisch wrote:
                  >
                  >A while loop has a condition. period. The only thing to change that is
                  >to introduce a uncoditioned loop, and use self-modifying code to make
                  >it a while-loop after that timer interrupt of yours.
                  >
                  or use a timer interrupt to interrupt the loop:
                  >
                  import signal, time
                  >
                  def func1(timeout):
                  >
                  def callback(signum , frame):
                  raise EOFError # could use a custom exception instead
                  signal.signal(s ignal.SIGALRM, callback)
                  signal.alarm(ti meout)
                  >
                  count = 0
                  try:
                  while 1:
                  count += 1
                  except EOFError:
                  for i in range(10):
                  count += 1
                  print count
                  >
                  for an utterly trivial task like the one in that example, the alarm
                  version runs about five times faster than a polling version, on my test
                  machine (ymmv):
                  No doubt that changing the flag asynchronously is a gain by delegating
                  the timing code to the OS. Yet the while loop still has a condition - so
                  you could as well set a flag in the signal handler an do it like this:

                  def func3(timeout):
                  global flag
                  flag = True
                  def callback(signum , frame):
                  global flag
                  flag = False
                  signal.signal(s ignal.SIGALRM, callback)
                  signal.alarm(ti meout)

                  count = 0

                  while flag or True:
                  count += 1


                  for i in range(10):
                  count += 1
                  print count

                  This is on my machine about 1.5 times slower than func1, but much more
                  readable especially wrt the OPs request of a condition being evaluated
                  after a certain timeout, as you don't repeat any code.

                  And apart from that, the overall gain of performance diminishes the very
                  moment anything non-trivial occurs in the loops body anyway.

                  Diez

                  Comment

                  • Fredrik Lundh

                    #10
                    Re: How to let a loop run for a while before checking for breakcondition?

                    Diez B. Roggisch wrote:
                    No doubt that changing the flag asynchronously is a gain by delegating
                    the timing code to the OS. Yet the while loop still has a condition -
                    you could as well set a flag in the signal handler an do it like this:
                    if the OP is obsessed with performance, why are you arguing that he
                    "could as well" use a slower solution ?
                    This is on my machine about 1.5 times slower than func1, but much more
                    readable
                    polling a global state flag being "much more readable" than handling an
                    exception in the usual way? surely you're joking.

                    are you sure you're posted the code you're writing about, btw. that "or
                    True" looks a bit suspicious.

                    </F>

                    Comment

                    • Diez B. Roggisch

                      #11
                      Re: How to let a loop run for a while before checking for breakcondition?

                      Fredrik Lundh schrieb:
                      Diez B. Roggisch wrote:
                      >
                      No doubt that changing the flag asynchronously is a gain by delegating
                      the timing code to the OS. Yet the while loop still has a condition -
                      you could as well set a flag in the signal handler an do it like this:
                      >
                      if the OP is obsessed with performance, why are you arguing that he
                      "could as well" use a slower solution ?
                      Maybe because it is the better solution in case of anything that has
                      more than one line of work to do? The Exception can interrupt
                      everywhere, the flag determines the point of interruption precisely.
                      >This is on my machine about 1.5 times slower than func1, but much more
                      >readable
                      >
                      polling a global state flag being "much more readable" than handling an
                      exception in the usual way? surely you're joking.
                      >
                      are you sure you're posted the code you're writing about, btw. that "or
                      True" looks a bit suspicious.
                      Yeah, that should have been a False - I added that after copying a first
                      version without that, instead of replacing it with the modified original
                      that I created to see what impact the short-circuiting "or" had.

                      Diez

                      Comment

                      • Hendrik van Rooyen

                        #12
                        Re: How to let a loop run for a while before checking for breakcondition?

                        "Claudio Grondi" <claudio.grondi @freenet.deWrot e:

                        | Fredrik Lundh wrote:
                        | Diez B. Roggisch wrote:
                        | >
                        | >A while loop has a condition. period. The only thing to change that is
                        | >to introduce a uncoditioned loop, and use self-modifying code to make
                        | >it a while-loop after that timer interrupt of yours.
                        | >
                        | >
                        | or use a timer interrupt to interrupt the loop:
                        | >
                        | import signal, time
                        | >
                        | def func1(timeout):
                        | >
                        | def callback(signum , frame):
                        | raise EOFError # could use a custom exception instead
                        | signal.signal(s ignal.SIGALRM, callback)
                        | signal.alarm(ti meout)
                        | >
                        | count = 0
                        | try:
                        | while 1:
                        | count += 1
                        | except EOFError:
                        | for i in range(10):
                        | count += 1
                        | print count
                        | >
                        | for an utterly trivial task like the one in that example, the alarm
                        | version runs about five times faster than a polling version, on my test
                        | machine (ymmv):
                        | >
                        | def func2(timeout):
                        | >
                        | gettime = time.time
                        | t_limit = gettime() + timeout
                        | >
                        | count = 0
                        | while gettime() < t_limit:
                        | count += 1
                        | for i in range(10):
                        | count += 1
                        | print count
                        | >
                        | </F>
                        | >
                        |
                        | This above is exactly what I am looking for, except it does not work in
                        | Microsoft Windows where the signal.alarm() function is not available.
                        |
                        | So now the only thing I would like to know is how to achieve the same
                        | functionality when running Python on a Microsoft Windows box.
                        |
                        | Claudio Grondi

                        It looks to me - but I could be wrong - that the time saved here is not because
                        of the condition test being replaced by the try-except, but because of the fact
                        that the call to gettime was eliminated - so you may get the most mileage by
                        using in line code in your loop that avoids calls to subroutines and simply let
                        it run and test for the end of the counter...

                        - Hendrik

                        Comment

                        • Hendrik van Rooyen

                          #13
                          Re: How to let a loop run for a while before checking forbreakconditi on?


                          "Claudio Grondi" <claudio.grondi @freenet.dewrot e:


                          | Diez B. Roggisch wrote:
                          | Claudio Grondi schrieb:
                          | >
                          | >>
                          | >Sometimes it is known in advance, that the time spent in a loop will
                          | >be in order of minutes or even hours, so it makes sense to optimize
                          | >each element in the loop to make it run faster.
                          | >One of instructions which can sure be optimized away is the check for
                          | >the break condition, at least within the time where it is known that
                          | >the loop will not reach it.
                          | >>
                          | >Any idea how to write such a loop?
                          | >>
                          | >e.g.
                          | >>
                          | >counter = 2*64
                          | >>
                          | >while counter(BUT DON'T CHECK IT THE FIRST ONE HOUR LONG):
                          | >
                          | >
                          | now = time.time()
                          | while time.time() - now < 3600.0 or some_other_cond ition:
                          | ...
                          | >
                          | >
                          | The short circuiting of the or will prevent the execution of
                          | some_other_cond ition.
                          | >
                          | > ... do something ... # and decrease the counter
                          | >>
                          | >Thanks for any hint, but in particular if related to timers on the
                          | >Windows 2000/XP system I am mainly working with.
                          | >>
                          | >What do you think about this idea? Does it make sense?
                          | >
                          | What idea?
                          | This one you haven't probably got from what I have written.
                          | I thought, that the introductory text gives enough context to be able to
                          | see what I mean, but I was apparently wrong.
                          |
                          | The idea is to speed up a loop by using a timer interrupt interfering
                          | with the loop, so that only after the timer interrupt would occur, the
                          | loop will start to check its break condition in each iteration.
                          | No checking of any kind in the loop should happen up to that time to
                          | minimize the number of operations in each iteration within the loop
                          | itself (i.e. the loop more or less won't know, that there is a timer on
                          | its way to change the loops behavior at a later time).
                          |
                          | I hope this above helps to understand what I would like to achieve.
                          |
                          | Claudio Grondi

                          I don't think this is usefully possible in python - the problem is that you will
                          simply replace one check - The expiry of the counter - with another - to see if
                          the interrupt has occurred already -

                          That said - the way I would do it would be to do something like this (in
                          horrible pseudo code):

                          loop_start:
                          do_something()
                          jump loop_start
                          if counter end_value:
                          break
                          jump loop_start
                          loop_end:


                          Interrupt_routi ne:
                          replace the first jump to loop_start with a bunch of no - ops
                          return

                          I don't think you can do this in python - it involves altering the running
                          loop - but hey maybe I can learn something here...

                          This example sort of exposes the break for what it is - a jump statement in
                          disguise - "look you cant recognise me - I am wearing dark glasses" - and
                          "continue" is exactly like that too - the only difference is that the one jumps
                          to the end, and the other to the beginning of the loop...

                          - Hendrik


                          Comment

                          • Claudio Grondi

                            #14
                            Re: How to let a loop run for a while before checking for breakcondition?

                            Hendrik van Rooyen wrote:
                            "Claudio Grondi" <claudio.grondi @freenet.deWrot e:
                            >
                            | Fredrik Lundh wrote:
                            | Diez B. Roggisch wrote:
                            | >
                            | >A while loop has a condition. period. The only thing to change that is
                            | >to introduce a uncoditioned loop, and use self-modifying code to make
                            | >it a while-loop after that timer interrupt of yours.
                            | >
                            | >
                            | or use a timer interrupt to interrupt the loop:
                            | >
                            | import signal, time
                            | >
                            | def func1(timeout):
                            | >
                            | def callback(signum , frame):
                            | raise EOFError # could use a custom exception instead
                            | signal.signal(s ignal.SIGALRM, callback)
                            | signal.alarm(ti meout)
                            | >
                            | count = 0
                            | try:
                            | while 1:
                            | count += 1
                            | except EOFError:
                            | for i in range(10):
                            | count += 1
                            | print count
                            | >
                            | for an utterly trivial task like the one in that example, the alarm
                            | version runs about five times faster than a polling version, on my test
                            | machine (ymmv):
                            | >
                            | def func2(timeout):
                            | >
                            | gettime = time.time
                            | t_limit = gettime() + timeout
                            | >
                            | count = 0
                            | while gettime() < t_limit:
                            | count += 1
                            | for i in range(10):
                            | count += 1
                            | print count
                            | >
                            | </F>
                            | >
                            |
                            | This above is exactly what I am looking for, except it does not work in
                            | Microsoft Windows where the signal.alarm() function is not available.
                            |
                            | So now the only thing I would like to know is how to achieve the same
                            | functionality when running Python on a Microsoft Windows box.
                            |
                            | Claudio Grondi
                            >
                            It looks to me - but I could be wrong - that the time saved here is not because
                            of the condition test being replaced by the try-except, but because of the fact
                            that the call to gettime was eliminated - so you may get the most mileage by
                            using in line code in your loop that avoids calls to subroutines and simply let
                            it run and test for the end of the counter...
                            >
                            - Hendrik
                            >
                            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(s ignal.SIGALRM, callback)
                            signal.alarm(ti meout)

                            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

                            Comment

                            • Hendrik van Rooyen

                              #15
                              Re: How to let a loop run for a while before checking for breakcondition?


                              "Claudio Grondi" <claudio.grondi @freenet.dewrot e:

                              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(s ignal.SIGALRM, callback)
                              | signal.alarm(ti meout)
                              |
                              | 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.0003118515014 65

                              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(s ignal.SIGALRM, callback)
                              signal.alarm(ti meout)

                              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



                              Comment

                              Working...