属性调用速度VS方法调用Python



你好,我有一个简单的问题,但我无法找到我正在寻找的直接比较。

我的问题是:

在Python中调用属性是否比调用方法更快?

我有一个游戏,我想检查玩家是否发现了一个行星。我可以调用:

def check_exploration(self, planet):
    return True if self.name in planet.explored_by else False

或检查属性:

self.game.player.logbook[planet.name].is_discovered == True

我问这个问题的原因是我想删除两种方法中的一种,但我不确定该采用哪种方法。

你可能已经注意到我在使用属性时有很多调用,这是因为我的游戏设计。每个对象都链接回我的游戏对象。所以我可以通过进入游戏对象并"返回"到目标对象的位置来访问每个对象。这是乏味的,但我发现它比在模块之间跳转要少得多,因为模块之间跳转会导致无休止的循环引用。

谢谢你的建议。

我制作了一些脚本,生成星系中行星的'planetsCount',并检查'testsCount'次数。(消息结束时的代码)一些结果:

Preparing was done in 0.0 seconds, planetsCount is 10, testsCount is 1000000
First test time is 2.50099992752 sec
Second test time is 2.5 sec
Preparing was done in 0.0160000324249 seconds, planetsCount is 1000, testsCount is 1000000
First test time is 6.97200012207 sec
Second test time is 2.54799985886 sec
Preparing was done in 0.406000137329 seconds, planetsCount is 100000, testsCount is 10000
First test time is 6.09399986267 sec
Second test time is 0.0310001373291 sec

检查通过属性有稳定的时间。在小列表中,通过"条目列表"进行检查的速度更快,但在大列表中却很慢。代码如下

import random
import base64
import time
class Planet(object):
    def __init__(self, state, name):
        self.is_discovered = state
        self.name = base64.b64encode(name)
class Galaxy(object):
    planets = {}
    explored = []
    def __init__(self, planetCount):
        for planetIndex in xrange(planetCount):
            planetName = base64.b64encode(str(planetIndex))
            is_discovered = random.choice([True, False])
            planet = Planet(is_discovered, planetName)
            self.planets.update({planetName: planet})
            if is_discovered:
                self.explored.append(planetName)
startTime = time.time()
planetsCount = 10
testsCount = 1000000
galaxy = Galaxy(planetsCount)
print "Preparing was done in {} seconds, planetsCount is {}, testsCount is {}".format(time.time() - startTime, planetsCount, testsCount)
startTime = time.time()
for x in xrange(testsCount):
    planetName = base64.b64encode(str(random.randint(0, planetsCount - 1)))
    planetName in galaxy.explored
print "First test time is {} sec".format(time.time() - startTime)
startTime = time.time()
for x in xrange(testsCount):
    planetName = base64.b64encode(str(random.randint(0, planetsCount - 1)))
    galaxy.planets[planetName].is_discovered
print "Second test time is {} sec".format(time.time() - startTime)

最新更新