2013-03-10 81 views
1

一个相对简单的问题:
如果我转换一个CPU绑定的瓶颈方法在Python的C扩展(大致实现相同的算法),将Python方法转换为C扩展的好处?

  • 多少增加的速度和性能,我应该期待什么?
  • 什么因素决定了?

更新: 人们似乎在抱怨缺乏具体细节。我主要试图理解什么因素会使得一段Python代码成为用C语言重写的好候选者(即,如果原始Python是CPU绑定的,何时移植到C实际上会提高速度)。

具体而言,这是我正在看的一段代码。基本上,它是一个递归方法,它接受两个列表(一列“列”,其中每列包含可能的值,可能在该列......基本上是一个模式),并看看是否有可能使小于n (通常是1)更改(其中一个更改可能是为列添加新值,添加新列,删除列等),以便存在一些值序列(每列中有一个值)可以从任一模式构建。它在精神上非常类似于计算字符串之间的编辑距离。这里的代码:

def CheckMerge(self, schemai, schemaj, starti, startj, \ 
       changesLeft, path): 
#  if starti == 0 and startj == 0: 
#   print '\n' 
#   print schemai.schema 
#   print '' 
#   print schemaj.schema 
    if starti == len(schemai.schema) and startj == len(schemaj.schema): 
     return (True, path) 
    if starti < len(schemai.schema): 
     icopy = schemai.schema[starti] 
    else: 
     icopy = [] 
    if startj < len(schemaj.schema): 
     jcopy = schemaj.schema[startj] 
    else: 
     jcopy = [] 
    intersect = set(icopy).intersection(set(jcopy)) 
    intersect.discard('') 
    if len(intersect) == 0: 
     if starti < len(schemai.schema) and \ 
      ('' in schemai.schema[starti] or changesLeft > 0): 

      if not '' in schemai.schema[starti]: 
       changesLeft -= 1 
      changesCopy = list(path) 
      changesCopy.append('skipi') 
      result,steps = self.CheckMerge(schemai, schemaj, starti+1, startj, \ 
            changesLeft, changesCopy) 
      if result: 
       return (result,steps) 
      elif not '' in schemai.schema[starti]: 
       changesLeft += 1 

     if startj < len(schemaj.schema) and \ 
      ('' in schemaj.schema[startj] or changesLeft > 0): 

      if not '' in schemaj.schema[startj]: 
       changesLeft -= 1 
      changesCopy = list(path) 
      changesCopy.append('skipj') 
      result,steps = self.CheckMerge(schemai, schemaj, starti, startj+1, \ 
            changesLeft, changesCopy) 
      if result: 
       return (result, steps) 
      elif not '' in schemaj.schema[startj]: 
       changesLeft += 1 

     if changesLeft > 0: 
      changesCopy = list(path) 
      changesCopy.append('replace') 
      changesLeft -= 1 
      result,steps = self.CheckMerge(schemai, schemaj, starti+1, startj+1, \ 
            changesLeft, changesCopy) 
      if result: 
       return (result, steps) 

     return (False, None) 
    else: 
     changesCopy = list(path) 
     changesCopy.append('merge') 
     result,steps = self.CheckMerge(schemai, schemaj, starti+1, startj+1, \ 
            changesLeft, changesCopy) 
     if result: 
      return (result, steps) 
     else: 
      return (False, None) 
+1

如果您发布当前的Python代码,它将会有所帮助。 – 2013-03-10 06:23:29

+1

您是否先尝试过Cython? – 2013-03-10 06:50:05

+0

根据您使用的数据以及算法的工作原理,速度的增加可能是从'1x'(=无)到大约'100x'。你的问题目前对这个网站太模糊了。你应该包括你有的Python代码,并提出有关该代码的具体问题。 – Bakuriu 2013-03-10 08:13:11

回答

1

这完全和完全取决于你的代码。 如果硬件支持您的某些代码,例如计算海明重量,进行AES加密,计算CRC,或者使用可矢量化的代码,则可以使用硬件指令来提高速度,以及你可以通过C代码访问它们,但不能使用python代码。

0

Python运行速度非常快,所以您需要一个明确的理由将Python函数转换为C,就像访问已经提到的硬件一样。但是,这是另一个原因。

Python(C Python)患有全局解释器锁(GIC)问题。 Python线程不能同时运行,一次只能运行一个线程。因此,您可以将线程特定的代码放入C中,这不受GIC问题的限制。一般来说,如果你认为你的Python代码很慢并且没有特定的原因,你可能需要适应更多的Python-ic编码约定,比如列表解析和其他在Python中找到的功能并没有太多的其他语言。

我的最终评论并不反映你的代码示例。相反,我将它作为我学习聆听大量Python演示文稿的一般智慧提供。