使用C加速Python中的列表操作

时间:2014-02-19 17:38:30

标签: c performance python-2.7 list-comprehension

我们假设pq是Python中常用长度为n的列表。每个列表按某种顺序包含range(n)的内容(这很重要!)。我们可以假设n很小(即不超过2 ^ 16)。我现在使用以下代码在这些列表上定义一个操作

def mult(p,q):
    return [q[i] for i in p]

显然,mult(p,q)再次是一个包含range(n)内容的列表。这个python代码是排列组合的一个例子(见http://en.wikipedia.org/wiki/Permutation)。

我想在Python中尽可能快地运行此代码。我尝试用numpy数组替换pq以查看这是否会加快速度,但在时间测试下差异可以忽略不计(注意numpy的设计不考虑上述功能)。我还为Python编写了一个C扩展来尝试加速,但这似乎没有帮助(但是我使用了PySequence_Fast_GET_ITEM之类的函数,它们可能与Python本身使用的函数相同)。

是否有可能在C中为Python编写一个新类型(如此处所述http://docs.python.org/2/extending/newtypes.html),它具有上述mult函数快速(呃)的属性?或者,实际上,用C编写任何程序都会给Python带来这样的类型。

我在问这个问题,看看我是不是在叫错树。特别是,Python基本上有一些固有属性,这意味着永远不会加速?我最感兴趣的是Python 2.7,但有兴趣知道Python 3 +的任何解决方案。

1 个答案:

答案 0 :(得分:2)

正如Abid Rahman的评论所指出的那样,正确使用NumPy比实现自己的C数据结构更好。

import numpy as np

p = np.array(range(1000))
q = np.array(range(1000))

%timeit [q[i] for i in p]
# 1000 loops, best of 3: 312 us per loop

%timeit q[p]
# 100000 loops, best of 3: 4.31 us per loop

NumPy基本上完成了你自己希望做的事情(将数组访问推送到C级别)。但是,如果您只是执行列表推导,那么所有循环都将在Python中处理,因此它不会比使用常规Python列表的原始循环快得多。