我将改进我的代码片段的性能,这将经常递归地获取子数组。
所以我使用了numpy.array而不是内置列表。因为,据我所知,在获取子数组时,numpy.array不会复制原始列表。
但是当我改为numpy.array时,表现变得更糟。所以我想知道原因。谢谢!
以下是我的代码片段和使用我得到的不同对象的执行时间:
import timeit
stat = '''
import numpy
def func(a):
a[len(a)-1] += 1
if len(a) == 1:
return a[0]
else:
return func(a[1:len(a)])
a1=[1,2,3,4,5,6,7,8,9,10]
a2=numpy.array([1,2,3,4,5,6,7,8,9,10])
'''
if __name__ == "__main__":
print "Execution time with build-in list: {0}".format(timeit.timeit('func(a1)', setup = stat, number = 1000))
print "Execution time with Numpy array: {0}".format(timeit.timeit('func(a2)', setup = stat, number = 1000))
在我的64位mac(Python 2.7.6 + Numpy 1.8.0rc1)上,输出为:
Execution time with build-in list: 0.00507998466492
Execution time with Numpy array: 0.0195469856262
答案 0 :(得分:1)
如果修改最后两行代码,您将获得相同的执行时间,如下所示:
print "Execution time with build-in list: {0}".format(timeit.timeit(
'func(a1)', setup = stat, number = 1000), 'gc.enable()')
print "Execution time with Numpy array: {0}".format(timeit.timeit(
'func(a2)', setup = stat, number = 1000), 'gc.enable()')
在这两种情况下,我们允许 timeit 打开所谓的垃圾收集,即在不再使用时释放内存的过程。上述修改返回,例如:
Execution time with build-in list: 0.00580596923828
Execution time with Numpy array: 0.00822710990906
具有相同的数量级。根据 timeit "的文档,默认情况下,它会暂时关闭垃圾收集。这种方法的优点在于它使独立时序更具可比性。这个缺点是垃圾收集可能是所测量功能性能的重要组成部分。"
应该使用什么方法,即使用或不使用垃圾收集,何时使用。另请注意,如果从时间模块应用time.time()块,您将获得更长的时间。
答案 1 :(得分:0)
感谢所有人'对于这个问题的答案和评论,你已经向我展示了有价值的信息来做出这个答案。
答案是这样的。在我的问题中导致numpy数组性能不佳的原因是访问单个项目并在numpy数组上分配内置类型比内置列表慢。实际上,存在获取numpy数组的子数组比内置列表的性能增益。但是在短阵列中增益太小,例如在我的例子中,len = 10的数组,所以丢失的小增益被这一行所取代:a[len(a)-1] += 1
我们在其中访问了单个项目并在内置类型int之间进行转换。
以下代码证明了原因:
import numpy
from timeit import timeit
stat = '''
import numpy
a1 = range(4000)
a2 = numpy.array(a1)
i = 0
'''
if __name__ == "__main__":
test_times = 1000
print '1. {0:.8f}'.format(timeit('a1[i]', setup = stat, number = test_times))
print '2. {0:.8f}'.format(timeit('a2[i]', setup = stat, number = test_times))
print '3. {0:.8f}'.format(timeit('i += a1[i]; ++i', setup = stat, number = test_times))
print '4. {0:.8f}'.format(timeit('i += a2[i]; ++i', setup = stat, number = test_times))
print '5. {0:.8f}'.format(timeit('a = a1[i:len(a1)]; ++i', setup = stat, number = test_times))
print '6. {0:.8f}'.format(timeit('a = a2[i:len(a2)]; ++i', setup = stat, number = test_times))
我的mac中的运行结果如下:
1. 0.00005913
2. 0.00017881
3. 0.00008607
4. 0.00084305
5. 0.01492000
6. 0.00053406
我们可以从上面的结果中得到这些: