Python列表与C阵列:慢100倍?

时间:2012-04-03 17:29:56

标签: python c arrays performance list

据我所知,Python列表是作为向量实现的。这就是为什么我无法解释为什么下面的代码在Python中比在等效的C代码中慢100倍(在3.1.3中,而且#34;仅在#34; 65x在python 3.2中)。

它只是重复提取列表的最大值nbExtract次:

nbValues = int(input())
nbExtract = int(input())
values = [int(value) for value in input().split()]

for loop in range(nbExtract):
   idMax = 0   
   for idValue in range(nbValues):
      if values[idMax] < values[idValue]:
         idMax = idValue
   print(values[idMax], end = ' ')
   values[idMax] = values[nbValues- 1]
   nbValues= nbValues - 1

注意nbExtract可能小于log(nbValues),因此对值进行排序通常较慢

我知道如何更快地完成它(例如使用内部max功能)但这对于高中学生来说是一个练习,我们只教他们基础知识(if / else,for,while和列表),而不是Python中可用的所有函数。

有没有办法在保持相同结构的同时提高速度?我已经尝试过Python的数组,但速度大致相同。

有谁知道为什么内部Python对列表操作的速度要慢得多?

<小时/> 根据要求,等效的C代码:

#include <stdio.h>
int main()
{
   int nbValues, nbExtract ;
   scanf("%d%d", &nbValues, &nbExtract);
   int values[nbValues];
   for (int idValue = 0; idValue < nbValues; idValue++)
      scanf("%d", &values[idValue]);

   for (int loop = 0; loop < nbExtract; loop++)
   {
      int idMax = 0;
      for (int idValue = 0; idValue < nbValues; idValue++)
         if (values[idMax] < values[idValue])
            idMax = idValue;
      printf("%d ", values[idMax]);
      values[idMax] = values[nbValues - 1];
      nbValues--;
   }
   return 0;
}

2 个答案:

答案 0 :(得分:2)

你可以通过微调来减少几秒钟。

def main():
    nbValues = int(input())
    values = [int(x) for x in input().split()]

    for loop in range(nbValues):
        idMax = 0   
        maxv = -2**64 # Not perfect
        for idValue in range(nbValues):
            v = values[idValue]
            if v > maxv:
                idMax = idValue
                maxv = v
        print(values[idMax], end = ' ')
        values[idMax] = values[nbValues- 1]
        nbValues = nbValues - 1

main()

我做了两处小改动。

  1. 我将整个代码块包装在一个函数中。函数块内的代码比顶层代码更快,因为变量查找可以通过索引完成,而不是通过在全局字典中查找变量名来完成。改进:我的电脑快了60%。

  2. 然后我通过缓存局部变量中的当前最大值来减少数组访问次数。这使得速度进一步提高了15%。

  3. 我尝试使用array模块,但没有提供进一步的收益。我并不感到惊讶,因为访问数组对象中的整数需要堆分配。

    通常,Python开发人员不关心优化Python来处理这种代码,并且他们提供了很好的理由。如果不采用内置函数,我不希望有任何进一步的改进。例如,以下代码在我的系统上的C版本的3倍之内,并且与Python程序员编写它的方式相匹配。

    nbValues = int(input())
    values = [int(x) for x in input().split()]
    values.sort(reverse=True)
    print(' '.join(str(x) for x in values))
    

    建议:减少输入大小。将阵列大小减半可以使速度提高300%,免费。

答案 1 :(得分:0)

编辑:抓住这个,我显然不会在这里说话。我的印象是Python的列表几乎都是链表,但事实并非如此。

Python的list类型并不完全是一个数组,至少在你想到数组/向量的意义上。 list类型更像是链表数据结构(易于插入,追加,删除元素等),但这也不是一个完全准确的描述。为了公平地比较C数组,我建议使用Numpy的array类型。

有关详细信息,请参阅此处:Python List vs. Array - when to use?