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

时间:2016-08-23 20:04:45

标签: python class optimization methods attributes

您好我有一个简单的问题,但我无法找到我想要的直接比较。

我的问题是:

调用属性是否比在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

我之所以提出这个问题的原因是因为我想删除这两种方法中的一种,但我不知道该走哪条路。

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

谢谢你的建议。

1 个答案:

答案 0 :(得分:1)

我制作了一些产生' 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

检查via属性是否有稳定的时间。 检查列表中的"项目"在小型列表上更快,但在大型列表上速度很慢。 代码如下

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)