我是python的新手。试图解决问题但由于TLE而陷入困境。以下代码花费了太多时间,大约10秒。现在,我想知道正常的嵌套循环是如此低效还是我做错了什么?
from datetime import datetime
arr = [1 for i in range(10000)]; # Originally had large size array of length ~10^4
l = len(arr);
ans = 0;
time1 = datetime.now();
# arr = sorted(arr);
for i in range(l):
for j in range(i+1,l):
ans+= arr[i]*arr[j];
print(datetime.now() - time1);
上述代码的输出:
0:00:10.595463
我已经知道python基于解释器,并且比C ++或Java等编译语言慢。但这很多!
由于python索引是在O(1)中完成的,所以这不应该花费太多时间。
请帮助我理解这是python的正常行为还是需要在此更改的任何内容。
虽然我可以使用numpy但是想以原生方式使用它。请帮忙。
答案 0 :(得分:1)
有些事情需要改进,尽管使用默认解释器的Python嵌套循环非常慢。
对于这样的脚本,您可以尝试Pypy而不是CPython:)
我的结果运行你的脚本:
$ python3 script.py
0:00:07.167943
$ pypy script.py
0:00:00.150436
In this other question你可以找到解释为什么两者之间的运行时间存在很大差异的原因。
PD :请不要在每个声明的末尾使用分号
答案 1 :(得分:1)
从总和中提取乘法会大大提高速度:
In [1]: arr = [1 for i in range(10000)]
In [2]: def calc2(arr):
...: ans = 0
...: for j in range(len(arr)):
...: ans += arr[j] * sum(arr[j+1:])
...: return ans
...:
In [3]: %timeit calc2(arr)
1 loop, best of 3: 1.02 s per loop
这比你发布的时间快了大约10倍。
但你应该使用numpy
进行数字运算。
下面我已将上面的计算直接转换为numpy
:
In [1]: import numpy as np
In [2]: def calc(arr):
...: ans = np.zeros_like(arr)
...: for j in range(len(arr)):
...: ans[j] = arr[j] * np.sum(arr[j+1:])
...: return np.sum(ans)
...:
In [3]: arr = np.random.rand(10000)
In [4]: %timeit calc(arr)
1 loop, best of 3: 181 ms per loop