2017-02-19 113 views
0

我是python的新手。正试图解决问题,但由于TLE而陷入困境。下面的代码花费了太多时间,大约10秒。现在,我想知道正常的嵌套循环是如此低效或我做错了什么?循环在Python-3中花费太多时间

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 

我已经知道蟒蛇是基于解释和比编译语言,如C++或Java慢。但这很多!

由于python索引是在O(1)中完成的,所以不需要太多时间。

请帮我理解,如果这是python的正常行为或任何需要改变的地方。

虽然我可以使用numpy,但想以本地方式使用它。请帮忙。

+0

你有49995000次的迭代,这似乎合法的给我。 –

+0

如果您计算出您正在执行的步骤数:使用99999个循环减少的10000个循环,执行3 * 49995000行代码需要一些时间并不奇怪。 –

+1

https://repl.it/FpH9/1 - 编辑后的版本将repl.it上的运行时间从11.5秒降至6.5秒,ish。 – TessellatingHeckler

回答

1

有些事情可以改进,尽管Python嵌套循环使用默认解释器的速度很慢。

对于这样一个脚本,你可以尝试Pypy替代的CPython的:)

我的结果运行过程中出现的脚本:

$ python3 script.py 
0:00:07.167943 

$ pypy script.py 
0:00:00.150436 

In this other question你可以找到为什么有这么大的差异的解释两者之间的运行时间。

PD:请不要在每个语句

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进行数字运算。

下面我已经做了计算的straightforwad转换上面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