Hi,
I've gone through the Queue class and done a number
of optimizations that resulted in a very significant speed
increase.  The modified verion and a test script are
attached.  I've only done a very simple test so far.

prior to optimizations using the existing Queue class
======================================
tavis@lucy: ~ > time python test.py
 
real    0m6.367s
user    0m6.260s
sys     0m0.020s

after to optimizations 
======================================
tavis@lucy: ~ > time python test.py
 
real    0m4.361s
user    0m4.320s
sys     0m0.020s

Difference
======================================
It shaves off 2.006 seconds (31%) from the original time

This could be worthwhile considering how central
queues are in WebKit.
Tavis 

p.s. sourceforge's mail server is taking hours 
to deliver things today. anyone know why?
That's why I cc'd all of you...
"""A multi-producer, multi-consumer queue."""

class Empty(Exception):
    "Exception raised by Queue.get(block=0)/get_nowait()."
    pass

class Full(Exception):
    "Exception raised by Queue.put(block=0)/put_nowait()."
    pass

class Queue:
    def __init__(self, maxsize=0):
        """Initialize a queue object with a given maximum size.

        If maxsize is <= 0, the queue size is infinite.
        """
        import thread
        self._init(maxsize)
        self.mutex = thread.allocate_lock()
        self.esema = thread.allocate_lock()
        self.esema.acquire()
        self.fsema = thread.allocate_lock()

        ##shortcut name-bindings
        self.mutexAcquire = self.mutex.acquire
        self.mutexRelease = self.mutex.release
        self.fsemaAcquire = self.fsema.acquire
        self.fsemaRelease = self.fsema.release
        self.esemaAcquire = self.esema.acquire 
        self.esemaRelease = self.esema.release

        self._put = self.queue.append
        
    def qsize(self):
        """Return the approximate size of the queue (not reliable!)."""
        self.mutexAcquire()
        n = len(self.queue)
        self.mutexRelease()
        return n

    def empty(self):
        """Return 1 if the queue is empty, 0 otherwise (not reliable!)."""
        self.mutexAcquire()
        n = not self.queue
        self.mutexRelease()
        return n

    def full(self):
        """Return 1 if the queue is full, 0 otherwise (not reliable!)."""
        self.mutexAcquire()
        n = ( self.maxsize > 0 and len(self.queue) == self.maxsize )
        self.mutexRelease()
        return n

    def put(self, item, block=1):
        """Put an item into the queue.

        If optional arg 'block' is 1 (the default), block if
        necessary until a free slot is available.  Otherwise (block
        is 0), put an item on the queue if a free slot is immediately
        available, else raise the Full exception.
        """
        theQueue = self.queue

        if block:
            self.fsemaAcquire()
        elif not self.fsemaAcquire(0):
            raise Full
        self.mutexAcquire()
        was_empty = not theQueue # ~= self._empty()
        self._put(item)
        if was_empty:
            self.esemaRelease()
        if not (self.maxsize > 0 and len(theQueue) == self.maxsize): # ~= not 
self._full():
            self.fsemaRelease()
        self.mutexRelease()

    def put_nowait(self, item):
        """Put an item into the queue without blocking.

        Only enqueue the item if a free slot is immediately available.
        Otherwise raise the Full exception.
        """
        return self.put(item, 0)

    def get(self, block=1):
        """Remove and return an item from the queue.

        If optional arg 'block' is 1 (the default), block if
        necessary until an item is available.  Otherwise (block is 0),
        return an item if one is immediately available, else raise the
        Empty exception.
        """
        theQueue = self.queue
        
        if block:
            self.esemaAcquire()
        elif not self.esemaAcquire(0):
            raise Empty
        self.mutexAcquire()
        was_full = (self.maxsize > 0 and len(theQueue) == self.maxsize) # ~= 
self._full()

        item = theQueue[0]
        del theQueue[0]
        
        if was_full:
            self.fsemaRelease()
        if theQueue: # ~= not self._empty():
            self.esemaRelease()
        self.mutexRelease()
        return item

    def get_nowait(self):
        """Remove and return an item from the queue without blocking.

        Only get an item if one is immediately available.  Otherwise
        raise the Empty exception.
        """
        return self.get(0)

    # Initialize the queue representation
    def _init(self, maxsize):
        self.maxsize = maxsize
        self.queue = []

#from Queue import Queue, Full, Empty
from Queue2 import Queue, Full, Empty

MAXSIZE = 1000
q = Queue(MAXSIZE)

def putThenGet():
    for i in range(MAXSIZE):
        q.put(i)

    for i in range(MAXSIZE):
        val = q.get()


if __name__ == '__main__':
    for i in range(100):
        putThenGet()

Reply via email to