[Stackless] question about performance while running the actor example in "Introduction to Concurrent Programming with Stackless Python"

Cui Jian ken at informatik.uni-bremen.de
Tue Nov 10 19:14:39 CET 2009


Dear all,

I've modified the actor example in "Introduction to Concurrent 
Programming with Stackless Python" to do a small performance test, by 
simply changing the displayer and made it do nothing.
As I run the system with 1000 robots, the update rate (as printed during 
the program running) is about 46 on my laptop (2.0GHz*2, 1.5 GB Ram, 
windows xp)
My question is, is it normal to have such a not very high update rate? 
because the running program is merely having 1000 robots doing simple 
movement (I also ignore the collision test), this is far too small 
amount of message-exchanges compared to the situation of a real massive 
multiplayer online game, isn't it?
Or did I do something wrong by modifying the codes (even if I only 
deleted the displaying parts)?
Or does this example itself lack of optimization, and doesn't reveal all 
the power of stackless...?

best,
Cui

======================================

import stackless
import math
import time

class actor:
    def __init__(self):
        self.channel = stackless.channel()
        self.processMessageMethod = self.defaultMessageAction
        stackless.tasklet(self.processMessage)()

    def processMessage(self):
        while 1:
            self.processMessageMethod(self.channel.receive())
        
    def defaultMessageAction(self,args):
        print args

class world(actor):
    def __init__(self):
        actor.__init__(self)
        self.registeredActors = {}
        stackless.tasklet(self.sendStateToActors)()

    def testForCollision(self,x,y):
        return 0
    
    def sendStateToActors(self):
        while 1:
            for actor in self.registeredActors.keys():
                actorInfo = self.registeredActors[actor]
                if self.registeredActors[actor][1] != (-1,-1):
                    VectorX,VectorY = 
(math.sin(math.radians(actorInfo[2])) * actorInfo[3],
                                       
math.cos(math.radians(actorInfo[2])) * actorInfo[3])
                    x,y = actorInfo[1]
                    x += VectorX
                    y -= VectorY
                    if self.testForCollision(x,y):
                        actor.send((self.channel,"COLLISION"))
                    else:                        
                        self.registeredActors[actor] = tuple([actorInfo[0],
                                                          (x,y),
                                                              actorInfo[2],
                                                              actorInfo[3]])
            worldState = [self.channel, "WORLD_STATE"]
            for actor in self.registeredActors.keys():
                if self.registeredActors[actor][1] != (-1,-1):
                    worldState.append( (actor, 
self.registeredActors[actor]))
            message = tuple(worldState)
            for actor in self.registeredActors.keys():
                actor.send(message)
            stackless.schedule()

    def defaultMessageAction(self,args):
        sentFrom, msg, msgArgs = args[0],args[1],args[2:]
        if msg == "JOIN":
            print 'ADDING ' , msgArgs
            self.registeredActors[sentFrom] = msgArgs
        elif msg == "UPDATE_VECTOR":
            self.registeredActors[sentFrom] = 
tuple([self.registeredActors[sentFrom][0],
                                                     
self.registeredActors[sentFrom][1],
                                                     msgArgs[0],msgArgs[1]])
        else:
            print '!!!! WORLD GOT UNKNOWN MESSAGE ' , args
            
World = world().channel

class display(actor):
    def __init__(self,world=World):
        self.updateTime = 0
        self.oldTime = time.time();
        actor.__init__(self)
        self.world = World
        self.icons = {}
        joinMsg = (self.channel,"JOIN",self.__class__.__name__, (-1,-1))
        self.world.send(joinMsg)

    def defaultMessageAction(self,args):
        sentFrom, msg, msgArgs = args[0],args[1],args[2:]
        currentTime = time.time()
        self.updateTime+=1
        if currentTime - self.oldTime>1:
            self.oldTime = currentTime;
            print '---->', self.updateTime
            self.updateTime = 0
        if msg == "WORLD_STATE":
            self.updateDisplay(msgArgs)
        else:
            print "UNKNOWN MESSAGE", args

    def updateDisplay(self,actors):
        return

display()

class basicRobot(actor):
    def __init__(self,location=(0,0),angle=135,velocity=1,world=World):
        actor.__init__(self)
        self.location = location
        self.angle = angle
        self.velocity = velocity
        self.world = world

        joinMsg =(self.channel,"JOIN",self.__class__.__name__,
                  self.location,self.angle,self.velocity)
        self.world.send(joinMsg)

    def defaultMessageAction(self,args):
        sentFrom, msg, msgArgs = args[0],args[1],args[2:]
        if msg == "WORLD_STATE":
            self.location = (self.location[0] + 1, self.location[1] + 1)
            self.angle += 1
            if self.angle >= 360:
                self.angle -= 360

            updateMsg = (self.channel, "UPDATE_VECTOR",
                         self.angle,self.velocity)
            self.world.send(updateMsg)
        elif msg == "COLLISION":
            self.angle += 73
            if self.angle >= 360:
                self.angle -= 360
        else:
            print "UNKNOWN MESSAGE", args

for i in range(1000):
    basicRobot(angle=135,velocity=5)
    
stackless.run()





More information about the Stackless mailing list