不作死就不会死--似乎还是元组性能好

def xwhile_stacks(n):
    stacks = [(0,n,None,None,)]
    while stacks:
        stg,n,possible,choice=stacks.pop()
        if stg==0:
            if n==1:
                res = 1,0
            else:
                stacks.append((1,n,[],n-1))
                stacks.append((0,1,None,None))
        else:
            value = 2*res[0] + 2**choice-1
            possible.append((value,choice))
            if choice > 1:
                stacks.append((1,n,possible,choice-1))
                stacks.append((0,n-choice+1,None,None))
            else:
                res = min(possible,key=lambda x:x[0])
    return res

我觉得对于stacks的元素,如果用list来替换tuple,由于list是可变序列,避免一些不必要的仅作占位符的None,同时直接通过索引来访问stack的成员,会不会更快些呢?

于是我这样:

def ywhile_stacks(n):
    stacks = [[0,n]]
    while stacks:
        c=stacks.pop()
        if c[0]==0:
            if c[1]==1:
                res = 1,0
            else:
                c[0]=1
                c.append([])
                c.append(c[1]-1)
                stacks.append(c)
                stacks.append([0,1])
        else:
            value = 2*res[0] + 2**c[3]-1
            c[2].append((value,c[3]))
            if c[3] > 1:
                c[3]=c[3]-1
                stacks.append(c)
                stacks.append([0,c[1]-c[3]])
            else:
                res = min(c[2],key=lambda x:x[0])
    return res

显然第二种写法对于人类而言是比较蛋疼的,而且不幸的是,它性能也更差.下面是i=20的时候,各自重复10次的最佳数据

>>> 
1 groups, 10 times
xwhile_stacks best time: 18.310476023494346
ywhile_stacks best time: 23.709957728138697

这说明一个什么问题?一个明智的编程做法是:先从人类考虑,写简单明了的版本,不要无聊地想"如果采用XX做法,性能会不会更好",等性能成了问题,再考虑改写.

posted @ 2014-03-18 13:35  LisPythoniC  阅读(215)  评论(0编辑  收藏  举报