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做法,性能会不会更好",等性能成了问题,再考虑改写.