2016-08-23 20 views
0

こんにちは私は簡単な質問がありますが、私が探していた直接の比較を見つけることができませんでした。属性呼び出し速度VSメソッド呼び出しPython

私の質問は次のとおりです。

は属性を呼び出すと、Pythonでメソッドを呼び出すよりも高速になりがちありません。

私はゲームを持っており、プレイヤーが惑星を発見したかどうかをチェックしたいと思います。私はそれを行うための2つの方法のいずれかを削除したいが、私は」ので、私は求めている理由がある

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

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

または属性を確認してください:私はへの呼び出しを行うことができますいずれかどちらに行くか分からない。

属性を使用しているときに私は多くの呼び出しがありますが、これは私のゲームデザインのためです。すべてのオブジェクトは私のゲームオブジェクトにリンクしています。だから、私はゲームオブジェクトに行き、ターゲットオブジェクトの場所に "戻る"ことで各オブジェクトにアクセスできます。面倒ですが、無限の循環参照を引き起こすモジュール間を飛び回るよりもずっと面倒ではないことがわかりました。

ありがとうございます。

+0

'planet.explored_by他false'を中self.nameだけのいずれかの方法が十分に速くなり、あなたのユースケースについてplanet.explored_by' – wim

+1

でself.nameを返す'べきである場合にtrueを返します下回っていました。パフォーマンス上の理由から、1つを他のものよりも選択することには意味がありません。どのスタイルでもコードを最も見やすくすることができます。 – 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

関連する問題