我们假设p
和q
是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数组替换p
和q
以查看这是否会加快速度,但在时间测试下差异可以忽略不计(注意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 +的任何解决方案。
答案 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列表的原始循环快得多。