2015-08-28 122 views
5

我有一本字典,使用在用Cython字典,尤其是里面nogil

my_dict = {'a':[1,2,3], 'b':[4,5] , 'c':[7,1,2]) 

我想用这个字典中的用Cython内nogil功能。所以,我试图宣布它为

cdef dict cy_dict = my_dict 

到目前为止还没有。

现在我需要迭代my_dict的键,如果值在列表中,请遍历它。在Python中,它很容易,如下所示:

for key in my_dict: 
     if isinstance(my_dict[key], (list, tuple)): 
      ###### Iterate over the value of the list or tuple 
      for value in list: 
       ## Do some over operation. 

但是,在Cython里面,我想要在nogil里面实现相同的功能。因为,python对象不允许在nogil内部,我都被卡在这里。

with nogil: 
    #### same implementation of the same in Cython 

任何人都可以帮我吗?

回答

16

唯一真正明智的选择是接受你需要GIL,不幸的是。涉及C++地图的选择不太明智,但可能很难申请您的具体情况。

您可以使用with gil:重新获取GIL。这里有一个明显的开销(使用GIL的部分不能并行执行,并且可能会有等待GIL的延迟)。然而,如果词典操纵是一块较大的用Cython码的一小块,这可能不是太差:

with nogil: 
    # some large chunk of computationally intensive code goes here 
    with gil: 
    # your dictionary code 
    # more computationally intensive stuff here 

其他较少明智的选择是使用C++图(沿侧其他C++标准库数据类型)。 Cython可以包装这些并自动转换它们。为了让基于您的数据。例如一个简单的例子:

from libcpp.map cimport map 
from libcpp.string cimport string 
from libcpp.vector cimport vector 
from cython.operator cimport dereference, preincrement 

def f(): 
    my_dict = {'a':[1,2,3], 'b':[4,5] , 'c':[7,1,2]} 
    # the following conversion has an computational cost to it 
    # and must be done with the GIL. Depending on your design 
    # you might be able to ensure it's only done once so that the 
    # cost doesn't matter much 
    cdef map[string,vector[int]] m = my_dict 

    # cdef statements can't go inside no gil, but much of the work can 
    cdef map[string,vector[int]].iterator end = m.end() 
    cdef map[string,vector[int]].iterator it = m.begin() 

    cdef int total_length = 0 

    with nogil: # all this stuff can now go inside nogil 
     while it != end: 
      total_length += dereference(it).second.size() 
      preincrement(it) 

    print total_length 

(你需要language='c++'编译这个)。

这样做的一个明显的缺点是,字典中的数据类型必须事先知道(它不能是一个任意的Python对象)。但是,由于您无法操作nogil块内的任意Python对象,所以无论如何您都受到相当的限制。

+0

谢谢。让我看看。数据类型在字典里面,我会把它保存为列表。对于编译,我可以遵循正常的Cython方式吗? –

+0

您需要按照[此处](http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#specify-language-in-setup-py)中所述的方式指定语言,但除此之外它应该正常工作办法。 – DavidW

+0

哦,真抱歉。我删除了评论,因为我发现它的工作。对不起, –

相关问题