<p>一些提示</p>
<h2>最小化太深的重定向</h2>
<p>您的代码在这里:</p>
<pre><code>def updateMap(self ,x ,y , Val):
oldval = self.RobotMap[x][y]
self.RobotMap[x][y]=self.RobotMap[x][y] + Val
if self.RobotMap[x][y] > self.mapMaxOcc:
self.RobotMap[x][y] = self.mapMaxOcc
elif self.RobotMap[x][y] < self.mapMaxFree:
self.RobotMap[x][y] = self.mapMaxFree
return oldval, self.RobotMap[x][y]
</code></pre>
<p>是否一直重复<code>self.RobotMap[x][y]</code>需要4级跃点才能获得值(self->;RobotMap->;[x]->;[y])</p>
<p>这可以优化:</p>
<h2>就地更新</h2>
<p>旧的:</p>
<pre><code>self.RobotMap[x][y]=self.RobotMap[x][y] + Val
</code></pre>
<p>新建(第二次保存现有值的跳转)</p>
<pre><code>self.RobotMap[x][y] += Val
</code></pre>
<h2>使用局部变量而不是深度嵌套结构</h2>
<pre><code>def updateMap(self ,x ,y , Val):
oldval = self.RobotMap[x][y]
newval = oldval + Val
if newval > self.mapMaxOcc:
newval = self.mapMaxOcc
elif newval < self.mapMaxFree:
newval = self.mapMaxFree
return oldval, newval
</code></pre>
<p>请注意,旧的返回<code>oldval, self.RobotMap[x][y]</code>不仅返回一个值,而且您已经修改了<code>self.RobotMap[x][y]</code>(因为它是可变的),因此如果您依赖它,您可能会感到惊讶。你知道吗</p>
<h2>使用全局变量而不是tempateData字典</h2>
<p>将dictionary更改为全局变量会稍微加快运行速度,因为它删除了一级ov间接寻址。我知道,这看起来很糟糕,但这可能会发生优化。你知道吗</p>
<h2>跳过返回<code>self.RobotMap[x][y]</code></h2>
<p>如果没有必要,或者已经更改了该值,请考虑保存返回的<code>self.RobotMap[x][y]</code>。你知道吗</p>
<h2>快速清除</h2>
<p>更改原件:</p>
<pre><code>def clear(self):
self.RobotMap = [[self.EmptyValue for i in xrange(self.sizeY)] for j in xrange(self.sizeX)]
</code></pre>
<p>收件人:</p>
<pre><code>def clear(self):
self.RobotMap = self.sizeY * [self.sizeY * [self.EmptyValue]]
</code></pre>
<p>我的测试表明,x=3,y=5的执行速度是x=3,y=5的两倍,更大的尺寸可能更好。你知道吗</p>
<h2>修改代码-从0.790581到0.479875秒</h2>
<pre><code>from math import degrees, radians, sin, cos, fabs
import time
templ_MapWidth = 800
templ_MapHeight = 600
templ_StartPosX = 500
templ_StartPosY = 300
templ_StartTheta = 0
templ_Resolution = 5
templ_mapThresholdFree = 126
templ_mapThresholdOcc = 130
templ_EmptyValue = 128
templ_mapMaxOcc = 137
templ_mapMaxFree = 119
templ_ServoPos = 0
templ_CurrentPosX = 0
templ_CurrentPosY = 0
templ_CurrentTheta = 0
templ_SafeZone = 10
templ_MapHeight = templ_MapHeight / templ_Resolution
templ_MapWidth = templ_MapWidth / templ_Resolution
templ_StartPosX = templ_StartPosX / templ_Resolution
templ_StartPosY = templ_StartPosY / templ_Resolution
class NewRobotMap(object):
def __init__(self, sizeX, sizeY, Resolution, RobotPosX, RobotPosY, RobotTheta, ServoPos, mapMaxOcc, mapMaxFree, OccValue, EmptyValue):
self.sizeX = sizeX
self.sizeY = sizeY
self.RobotPosX = int(RobotPosX)
self.RobotPosY = int(RobotPosY)
self.mapResolution = int(Resolution)
self.StartPosX = int(RobotPosX)
self.StartPosY = int(RobotPosY)
self.RobotTheta = float(RobotTheta)
self.EmptyValue = EmptyValue
self.ServoPos = ServoPos
self.mapMaxOcc = mapMaxOcc
self.mapMaxFree = mapMaxFree
self.mapOccValue = OccValue
self.RobotPosOldX = ""
self.RobotPosOldY = ""
def clear(self):
self.RobotMap = self.sizeX * [self.sizeY * [self.EmptyValue]]
def updateMap(self, x, y, Val):
oldval = self.RobotMap[x][y]
newval = oldval + Val
if newval < self.mapMaxFree:
return oldval, self.mapMaxFree
if newval > self.mapMaxOcc:
return oldval, self.mapMaxOcc
return oldval, newval
def setOcc(self, x, y):
self.RobotMap[x][y] = self.mapMaxOcc
def updateRobot(self, theta, x, y):
robotThetaold = self.RobotTheta
self.RobotTheta = float(theta)
self.RobotPosX = int(round(self.StartPosX + float(int(x)/self.mapResolution), 0))
self.RobotPosY = int(round(self.StartPosY - float(int(y)/self.mapResolution), 0))
if x != self.RobotPosOldX or y != self.RobotPosOldX:
self.RobotPosOldX = x
self.RobotPosOldY = y
return True
else:
self.RobotPosOldX = x
self.RobotPosOldY = y
return False
def getRobotPos(self):
return self.RobotPosX, self.RobotPosY
def display(self):
s = [[str(e) for e in row] for row in self.RobotMap]
lens = [len(max(col, key=len)) for col in zip(*s)]
fmt = '\t'.join('{{:{}}}'.format(x) for x in lens)
table = [fmt.format(*row) for row in s]
print '\n'.join(table)
def updateServoPos(self, newServoPos):
self.ServoPos = newServoPos
def updateSonarCalcMapVal(org, new):
mapThresholdFree = templ_mapThresholdFree
mapThresholdOcc = templ_mapThresholdOcc
#oldval
if org <= mapThresholdFree:
oldval = 0
elif mapThresholdFree < org < mapThresholdOcc:
oldval = 1
elif org >= mapThresholdOcc:
oldval = 2
# newval
if new <= mapThresholdFree:
newval = 0
elif mapThresholdFree < new < mapThresholdOcc:
newval = 1
elif new >= mapThresholdOcc:
newval = 2
if oldval != newval:
return newval
else:
return 'n'
def dur(op=None, clock=[time.time()]):
if op != None:
duration = time.time() - clock[0]
print '%s finished. Duration %.6f seconds.' % (op, duration)
clock[0] = time.time()
def updateIRWrite(RobotPos, coord, updateval):
XtoUpdate = RobotPos[0] + coord[0]
YtoUpdate = RobotPos[1] - coord[1]
newval = updateSonarCalcMapVal(*mymap.updateMap(XtoUpdate, YtoUpdate, updateval))
########### main Script #############
mymap = NewRobotMap(templ_MapWidth, templ_MapHeight, templ_Resolution, templ_StartPosX, templ_StartPosY, templ_StartTheta, templ_ServoPos, templ_mapMaxOcc, templ_mapMaxFree, templ_mapThresholdOcc, templ_EmptyValue)
mymap.clear()
dur()
for x in xrange(0, 10001*40):
updateIRWrite((100, 100), (10, 10), 1)
dur("loops")
</code></pre>
<h2>结论</h2>
<p>为了做正确的工作,代码肯定需要检查。例如,有些方法根本不使用,有些调用从不使用返回值。你知道吗</p>
<p>但可以看到一些优化。一般来说,可以遵循以下原则:</p>
<ol>
<li>首先让代码正确运行</li>
<li>澄清什么是可接受的速度,如果没有必要,不要优化</li>
<li>测量,轮廓</li>
<li>在最繁忙的循环中开始优化,就有最好的机会加快速度。在它们里面,每一行代码都很重要。你知道吗</li>
</ol>