Created
August 17, 2011 23:39
-
-
Save j0hn/1152932 to your computer and use it in GitHub Desktop.
Checkout models
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding: utf-8 | |
""" | |
Checkout queue test, a test between two models of queues on supermarkets | |
and banks and stuff like that. | |
The two models tested are: | |
Independent checkouts Single queue | |
--------------------- ----------- | |
[C] | [C] | [C] [C] | [C] | [C] | |
o o o o o o | |
o o o _______ _______ | |
o o o o | |
o o o o o | |
o o o ------- | |
o o o o o o | |
----- o | |
o o o | |
In the independent model each checkout takes care of it queue but | |
in the single queue model each checkout takes care of the single queue | |
""" | |
import sys | |
import time | |
import random | |
import threading | |
DEFAULT_CHECKOUTS = 30 | |
DEFAULT_PEOPLE_PER_CHECKOUT = 10 | |
class IndependentCheckout(threading.Thread): | |
""" | |
Independent checkout, has an amount of persons that | |
it will be consumed eventually. | |
""" | |
def __init__(self, main_queue, amount): | |
""" | |
main_queue is the complete set of checkouts, when this checkout | |
has people it belongs to that set and does not belong when it's empty. | |
""" | |
threading.Thread.__init__(self) | |
self.queue = range(amount) | |
self.amount = amount | |
self.main_queue = main_queue | |
self.main_queue.append(self) | |
def pop(self): | |
rnd_time = random.uniform(0, 0.3) | |
time.sleep(rnd_time) | |
self.queue.pop() | |
def run(self): | |
while len(self.queue) > 0: | |
self.pop() | |
self.main_queue.remove(self) | |
class SingleCheckout(threading.Thread): | |
""" | |
A Single checkout that consumes people from the main queue. | |
Used to model the single queue checkout. | |
""" | |
def __init__(self, main_queue): | |
""" | |
mainQueu it's the unique queue that exists on the single model. | |
""" | |
threading.Thread.__init__(self) | |
self.main_queue = main_queue | |
def pop(self): | |
rnd_time = random.uniform(0, 0.3) | |
try: | |
self.main_queue.pop() | |
except IndexError: | |
return | |
time.sleep(rnd_time) | |
def run(self): | |
while len(self.main_queue) > 0: | |
self.pop() | |
def lazy_wait_until_empty(queue): | |
""" | |
Waits until queue it's empty waiting a short amount of time | |
between checks. | |
""" | |
while len(queue) > 0: | |
time.sleep(0.001) | |
def run_threaded(): | |
""" | |
Runs the model with independent checkout and returns the | |
time that took to complete it. | |
""" | |
main_queue = [] | |
for _ in range(CHECKOUTS): | |
checkout = IndependentCheckout(main_queue, PEOPLE_PER_CHECKOUT) | |
checkout.start() | |
start = time.time() | |
lazy_wait_until_empty(main_queue) | |
end = time.time() | |
return end - start | |
def run_single(): | |
""" | |
Runs the model with a single queue and a lot of checkout that | |
consume people from the same queue. returns the | |
time that took to complete it. | |
""" | |
main_queue = range(CHECKOUTS * PEOPLE_PER_CHECKOUT) | |
for _ in range(CHECKOUTS): | |
checkout = SingleCheckout(main_queue) | |
checkout.start() | |
start = time.time() | |
lazy_wait_until_empty(main_queue) | |
end = time.time() | |
return end - start | |
if __name__ == "__main__": | |
if len(sys.argv) < 2 or "-h" in sys.argv or "--help" in sys.argv: | |
print "Usage: python %s METHOD [checkouts] [people_per_checkout]\n" % \ | |
sys.argv[0] | |
print "METHOD can be Independent, Single or Both" | |
sys.exit(1) | |
method = sys.argv[1] | |
if len(sys.argv) > 3: | |
CHECKOUTS = int(sys.argv[2]) | |
else: | |
CHECKOUTS = DEFAULT_CHECKOUTS | |
if len(sys.argv) > 4: | |
PEOPLE_PER_CHECKOUT = int(sys.argv[3]) | |
else: | |
PEOPLE_PER_CHECKOUT = DEFAULT_PEOPLE_PER_CHECKOUT | |
if method.lower() == "independent" or method.lower() == "both": | |
print "Independent took: %.3f seconds" % run_threaded() | |
if method.lower() == "single" or method.lower() == "both": | |
print "Single took: %.3f seconds" % run_single() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment