2013-03-10 85 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演示文稿的一般智慧提供。