1

我有一些 Python 代码比它应该的要慢得多。

#Generate planets
for t in range(stars*3): #There are 3 planets for every star, but not every star will have 3 planets
    theplanet=Planet()

    if random.randint(0,100) <= 25: #25% of planets have life
        theplanet.tl=random.randint(1,9)    #With a random tech level
    else:
        theplanet.tl=0  #The rest don't

    theplanet.star=stardict[random.choice(list(stardict.keys()))]     #Choose a random star
    theplanet.star.planets+=(theplanet,)    #Append the new planet to the star's list of planets
    theplanet.name=theplanet.star.name+"-"+str(len(theplanet.star.planets)) #Name the planet Starname-X, where X is the length of the star's planets tuple. Since this increases every time a planet is added, it will be 1 for the first planet, 2 for the next, etc...

    if math.floor((t/(stars*3))*100)==(t/(stars*3))*100: print("Generating planets: "+str((t/(stars*3))*100)+"% done.")

我很确定瓶颈在star=stardict[random.choice(list(etc... 行。我在这里猜测,但我假设 dicts 通过搜索 dict 中的每个条目并查看哪个具有正确的键来工作。我再次假设,列表只会在从条目号派生的内存位置读取信息,并且对于非常大的(准确地说是 200,000 个条目)列表/字典要快得多。

将字典的条目转换为列表会使这段代码更快吗?我该怎么做(我以为我看到了它的功能,现在正在查看文档......)?有没有其他人注意到可以加快速度的方法?

4

3 回答 3

4

您每次通过循环创建一个列表,但该列表是不变的。将其移出循环。

starlist=list(stardict.keys())
...
    theplanet.star=stardict[random.choice(starlist)]     #Choose a random star

问题几乎肯定不在字典查找中。它们基于非常快的哈希表。

于 2013-03-04T17:35:43.547 回答
2
  1. 将列表生成list(stardict.keys())移到循环之外

  2. 尝试分析您的代码(文档

  3. 假设您正在运行 CPython,请检查您的代码是否可以使用Pypy运行。由于其优化的 JIT,这可能会带来更好的性能

于 2013-03-04T17:45:00.780 回答
0

您仅将密钥用作中间值来选择 stardict 中的随机项目。您可以直接使用字典的值列表:

#Generate planets
starlist = stardict.values()
for t in range(stars*3): #There are 3 planets for every star, but not every star will have 3 planets
    theplanet=Planet()

    if random.randint(0,100) <= 25: #25% of planets have life
        theplanet.tl=random.randint(1,9)    #With a random tech level
    else:
        theplanet.tl=0  #The rest don't

    theplanet.star=random.choice(starlist)     #Choose a random star
    theplanet.star.planets+=(theplanet,)    #Append the new planet to the star's list of planets
    theplanet.name=theplanet.star.name+"-"+str(len(theplanet.star.planets)) #Name the planet Starname-X, where X is the length of the star's planets tuple. Since this increases every time a planet is added, it will be 1 for the first planet, 2 for the next, etc...

    if math.floor((t/(stars*3))*100)==(t/(stars*3))*100: print("Generating planets: "+str((t/(stars*3))*100)+"% done.")
于 2013-03-04T18:00:04.470 回答