当前位置: 首页 > 面试题库 >

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

南门正祥
2023-03-14
问题内容

我们正在做一些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)。这就是为什么它要快得多的原因。



 类似资料:
  • 问题内容: 在这段代码中,为什么不按我的意愿初始化我的数组?是不是for-each循环并非旨在做到这一点,或者我只是没有正确使用它? 问题答案: for-each循环不适用于这种情况。您不能使用for-each循环来初始化数组。您的代码: 将转换为以下内容: 如果这是一个对象数组,它仍然会失败。基本上,for-each依次将集合或数组中的每个条目分配给您提供的变量,然后可以使用该变量。该变量 不

  • 本文向大家介绍python 循环while和for in简单实例,包括了python 循环while和for in简单实例的使用技巧和注意事项,需要的朋友参考一下 python 循环while和for in简单实例 以上这篇python 循环while和for in简单实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。

  • 我有一个看起来很简单的问题,但由于某种原因我无法绕过它。基本上我的程序正在导致一个无限循环,我不知道为什么。 下面是我陷入的特定循环: 当我运行它时,它总是问我输入列#。我给它一个数字,它接受这个数字,$response变为True,但while循环继续运行,就好像<code>的$response</code>为false一样。我是Perl新手,所以可能我遗漏了一些东西,但是($response=

  • 问题内容: 一个简单的程序,用于计算数字平方并存储结果: 这两个选项的数组处理是否可能有所不同?我的实际程序会有一些更复杂的东西,但这 是我需要尽可能简单地并行化的一种计算方式 ,但没有这种结果。 问题答案: 从以下文档中: 如果您知道所调用的函数基于已编译的扩展,该扩展会在大多数计算过程中释放Python全局解释器锁(GIL)… 问题在于,在这种情况下,您不知道这一点。Python本身仅允许一次

  • 问题内容: 我读到 增强的for循环 比普通的 for循环 更有效: http://developer.android.com/guide/practices/performance.html#foreach 当我搜索它们的效率之间的差异时,我发现的是:如果是普通的for循环,我们需要一个额外的步骤来找出数组的长度或大小等, 但这是唯一的原因,增强的for循环优于普通的for循环吗?在那种情况下,

  • 主要内容:Python for循环的具体应用Python 中的循环语句有 2 种,分别是 while 循环和 for 循环,前面章节已经对 while 做了详细的讲解,本节给大家介绍 for 循环,它常用于遍历字符串、列表、元组、字典、集合等序列类型,逐个获取序列中的各个元素。 for 循环的语法格式如下: for 迭代变量 in 字符串|列表|元组|字典|集合:     代码块 格式中,迭代变量用于存放从序列类型变量中读取出来的元素,所以