2016-08-23 45 views
0

嗨,我有一个简单的问题,但我无法找到我正在寻找的直接比较。属性调用速度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 

我问的原因是因为我想删除的做这件事的两种方法之一,但我我不确定要走哪条路。

正如你可能已经注意到,当使用属性时,我有很多电话,这是因为我的游戏设计。每个对象都链接回我的游戏对象。所以我可以通过访问游戏对象并“回退”到目标对象的位置来访问每个对象。这是乏味的,但我发现它比在模块之间跳转导致无尽的循环引用混乱少得多。

感谢您的建议。

+0

'返回True如果self.name在planet.explored_by其他FALSE'应该只是'在planet.explored_by' – wim

+1

返回self.name对于你的使用情况,无论哪种方式将是足够快。出于性能原因,选择其中之一是没有意义的。选择任何风格使代码看起来最好。 – wim

+0

换句话说,[过早优化是万恶之源](http://c2.com/cgi/wiki?PrematureOptimization) – Barmar

回答

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 

经由属性检查具有稳定的时间。 通过“列表中的项目”在小列表中检查速度更快,但在大列表中速度很慢。 代码低于

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) 
+0

谢谢。这很有用。因为我不希望击中1000个星球标志。 – Sorade