【发布时间】:2018-03-18 14:37:39
【问题描述】:
我正在做一个项目,我必须遍历大型数组(列表),按索引访问每个项目。 通常这涉及根据条件检查每个元素,然后可能更新其值。
我注意到与例如在 C# 中执行类似操作相比,这非常慢。这是一个简单地遍历数组并重新分配每个值的示例:
C#:
var a = new double[10000000];
var watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < a.Length; i++)
{
a[i] = 1.0;
}
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
//About 40ms
Python:
a = []
for i in range(0, 10000000):
a.append(0.0)
t1 = time.clock()
for i in range(0, 10000000):
a[i] = 1.0
t2 = time.clock()
totalTime = t2-t1
//About 900ms
这里的 python 代码似乎慢了 20 倍以上。 我对python比较陌生,所以我无法判断这种性能是否“正常”, 或者如果我在这里做错了什么。我正在运行 Anaconda 作为我的 python 环境,PyCharm 是我的 IDE。
注意:我曾尝试在 numpy 数组上使用 nditer,但没有显着提高性能。
非常感谢任何提示!
更新: 我刚刚比较了以下两种方法:
#timeit: 43ms
a = np.random.randn(1000,1000)
a[a < 0] = 100.0
#timeit: 1650ms
a = np.random.randn(1000,1000)
for x in np.nditer(a, op_flags=['readwrite']):
if (x < 0):
x[...] = 100.0
看起来第一种(矢量化)方法是这里的方法......
【问题讨论】:
-
stackoverflow.com/questions/10712002/… 这个问题可能会有所帮助。是否以某种方式创建带有“附加”的列表效率低下?
-
nditer不承诺性能。 -
这里你称之为 first-approach,
a[a<0] = 100.0就是 numpy 中经常提到的 vectorization。 -
谢谢@sascha,我会研究一下向量化到底指的是什么