[Twisted-Python] Twisted Python vs. "Blocking" Python: Weird performance on small operations.

Reza Lotun rlotun at gmail.com
Tue Oct 13 10:04:06 EDT 2009


Hi Dirk,

I took a look at your code sample and got the async benchmark to run
with the following values:
*** Starting Asynchronous Benchmarks.

  -> Asynchronous Benchmark (1 runs) Completed in 0.000181913375854 seconds.
  -> Asynchronous Benchmark (10 runs) Completed in 0.000736951828003 seconds.
  -> Asynchronous Benchmark (100 runs) Completed in 0.00641012191772 seconds.
  -> Asynchronous Benchmark (1000 runs) Completed in 0.0741751194 seconds.
  -> Asynchronous Benchmark (10000 runs) Completed in 0.675071001053 seconds.
  -> Asynchronous Benchmark (100000 runs) Completed in 7.29738497734 seconds.

*** Asynchronous Benchmarks Completed in 8.16032314301 seconds.

Which, though still quite a bit slower than the synchronous version,
is still much better than the 40 sec. mark that you were experiencing.
My modified version simply returned defer.succeed from your aync
block-compute functions.

i.e. Instead of your initial example:
def int2binAsync(anInteger):
    def packStruct(i):
        #Packs an integer, result is 4 bytes
        return struct.pack("i", i)

    d = defer.Deferred()
    d.addCallback(packStruct)

    reactor.callLater(0,
                      d.callback,
                      anInteger)

    return d

my version does:

def int2binAsync(anInteger):
    return defer.succeed(struct.pack('i', anInteger))

A few things to note in general however:
1) Twisted shines for block I/O operations - i.e. networking. A
compute intesive process will not necessarily yield any gains in
performance by using Twisted since the Python GIL exists (a global
lock).

2) If you are doing computations that use a C module (unforunately
struct pre 2.6 I believe doesn't use a C module), there may be a
chance that the C module releases the GIL, allowing you to do those
computations in a thread. In this case you'd be better off using
deferToThread as suggested earlier.

3) There is some (usually minimal but it exists) overhead to using
Twisted. Instead of computing a bunch of stuff serially and returning
your answer as in your sync example, you're wrapping everything up in
deferreds and starting a reactor - it's definitely going to be a bit
slower than the pure synchronous version for this case.

Hope that makes sense.

Cheers,
Reza


-- 
Reza Lotun
mobile: +44 (0)7521 310 763
email:  rlotun at gmail.com
work:   reza at tweetdeck.com
twitter: @rlotun



More information about the Twisted-Python mailing list