为什么Python对于简单的for循环如此慢?

我们正在做一些kNNSVD实现Python编写的。其他人选择了Java。我们的执行时间非常不同。我使用cProfile查看我在哪里出错,但实际上一切都很好。是的,我numpy也使用。但是我想问一个简单的问题。

total = 0.0

for i in range(9999): # xrange is slower according

for j in range(1, 9999): #to my test but more memory-friendly.

total += (i / j)

print total

此摘要在我的计算机上耗时31.40s。

此代码的Java版本在同一台计算机上花费1秒或更短的时间。我想类型检查是此代码的主要问题。但是我应该为我的项目做很多这样的操作,我认为9999 *9999的数目不是很大。

我想我犯错了,因为我知道Python已被许多科学项目使用。但是为什么这段代码这么慢,我该如何处理更大的问题呢?

我应该使用JIT编译器Psyco吗?

回答:

我也说这个循环问题只是一个例子。代码并不像这样简单,因此很难将改进/代码示例付诸实践。

另一个问题是,我可以实现大量的数据挖掘和机器学习算法,与numpyscipy,如果我正确地使用它?

回答:

我想我犯错了,因为我知道Python已被许多科学项目使用。

他们大量使用SciPy(NumPy是最重要的组件,但我听说围绕NumPyAPI开发的生态系统更为重要),这些速度 大大_加快了这些项目所需的各种操作。这是您做错的事情:您不是用C编写 _关键

代码。Python对于一般而言的开发非常有用,但是放置适当的扩展模块本身就是至关重要的优化(至少在处理数字时)。

。Python是一种非常糟糕的语言,用于实现紧密的内部循环。

默认的(目前是最受欢迎和广泛支持的)实现是一个简单的字节码解释器。即使是最简单的操作(例如整数除法)也可能需要数百个CPU周期,多个内存访问(常见的类型检查),多个C函数调用等,而不是几个(对于整数,甚至是单个)除法)指令。此外,该语言具有许多抽象设计,这增加了开销。如果使用xrange,循环会在堆上分配9999个对象;如果使用xrange,则会在堆上分配更多的对象range(9999

* 9999整数减去256 *

256左右的高速缓存小整数)。此外,该xrange版本还会在每次迭代时调用一个方法来进行扩展-range如果未专门优化序列的迭代,则版本也是如此。但是,它仍然需要整个字节码分配,这本身是非常复杂的(当然,与整数除法相比)。

看到什么是JIT会很有趣(我建议使用PyPy而不是Psyco,后者不再积极开发,而且范围也非常有限-

尽管对于这个简单的示例来说,它可能很好用)。经过一小部分的迭代后,它应该会产生一个几乎最佳的机器代码循环,并增加一些保护措施-

简单的整数比较,如果失败,则跳转-

以保持正确性,以防您在该列表中出现字符串。Java可以做同样的事情,只是更快(不必先跟踪),并且只需较少的防护(至少如果使用ints)。这就是为什么它要快得多的原因。

以上是 为什么Python对于简单的for循环如此慢? 的全部内容, 来源链接: utcz.com/qa/406983.html

回到顶部