编程不是简单的堆砌代码,编写过程中也需要考虑执行效率,假如一段代码的计算复杂度较高,数据量一大就很难在有限时间内得到合理的结果,因此需要在编写代码的时候,尽量考虑计算的复杂度,减少无效的循环,多采用简单运算指令,减少逻辑判断,减少嵌套,在此基础上再考虑代码的可读性,以便于团队合作。
最近碰上一个例子,有一个人提出了一个很小的需求:有两个数列,有可能一个长一个短,也可能一样长,需要将两个数列相加,并补上长数列多出来的元素,得到第三个数列,例如a = [1,2,3,4,5], b=[1,2,3],最后得到数列c=[2,4,6,4,5],需求很简单,然后一个新人给出了如下的代码(用PYTHON实现):
a = [1,2,3,4,5]
b = [9,8,7,6,5]
def judge1(a,b):
c = []
if len(a) > len(b):
for i in range(len(b)):
c.append(a[i]+b[i])
for j in range(len(a) - len(b)):
c.append(a[len(b)+j])
if len(b) > len(a):
for i in range(len(a)):
c.append(a[i]+b[i])
for j in range(len(b) - len(a)):
c.append(b[len(a)+j])
if len(a) == len(b):
for i in range(len(b)):
c.append(a[i]+b[i])
看以上代码,一堆的循环和判断,并有许多重复代码,可读性极差,这是初学者常犯的错误。然后第二个人提出了优化方案:
def judge2(a,b):
i=0
for data in a:
if(i>=len(b)):
b.append(data)
else:
b[i]+=data;
i+=1
return b
从代码上可以看出已经得到了很大的优化,原来十多行的代码,现在只要6、7行就能搞定了,代码可读性很高,很容易理解,但这只里仍然存在一个问题:如果a比b短,则运行效率较高,但是如果a比b长呢,则性能会大大下降,因为循环的次数会大大增加,输入不同的数据,执行性能就会巨大的差别,同时中间变量也发生了变化。
因此又有了第三个方案:第一步,短的向量,自动补齐0元素,并保证两个向量的长度一致,第二步:两个向量直接相加,这样就可以大大提高代码的运行效率,如下:
def judge3(a, b):
if len(a)< len(b):
l = len(b)-len(a)
t = a + [0 for x in range(0, l)]
k = b
else:
l = len(b)-len(a)
t = b + [0 for x in range(0, l)]
k = a
result = [t[i] + k[i] for i in range(0,len(t))]
print result
如上代码,代码很容易理解,首先判断两个向量的长度,短的自动补齐0元素,然后两个向量进行对位相加,最后就能得到结果,代码很容易理解,非常pythonic,性能也很高,不会因为a和b长度的变化有明显的性能偏差,第一种方法就不说了,第二种方法和第三种方法的性能比较如下:
if __name__ =='__main__':
a = [2000 for x in range(0, 10000)]
b = [100 for x in range(0, 100)]
time1= time.time()
for i in range(1000):
judge2(a,b)
judge3(b,a)
time2= time.time()
print u"方法2总用时:%d" % (time2-time1)
time1= time.time()
for i in range(1000):
judge2(a,b)
judge3(b,a)
time2= time.time()
print u"方法3总用时:%d" % (time2-time1)
最后得出如下测试结果:
方法2总用时:6
方法3总用时:1
假如变换a和b,方法3的性能没有明显的偏离。
当然,上面这个只是最近碰到的一个例子,平时工作中还会碰到许多类似的情况,在编写代码的时候都需要仔细考虑,不要操之过急,编程不是简单的堆砌代码。这方面也可以通过阅读《编程珠玑》《代码整洁之道》等书籍得到进一步的提高。
转载于:https://blog.51cto.com/casey/1791201