簡體   English   中英

Cythonize字符串的所有拆分列表

[英]Cythonize list of all splits of a string

我正在嘗試加速一段代碼,生成所有可能的字符串拆分。

splits('foo') -> [('f', 'oo'), ('fo', 'o'), ('foo', '')]

python中的代碼非常簡單:

def splits(text):
    return [(text[:i + 1], text[i + 1:])
            for i in range(len(text))]

有沒有辦法通過cython或其他方式加快速度? 對於上下文,此代碼的更大目的是找到具有最高概率的字符串的拆分。

這不是Cython傾向於幫助的問題。 它使用切片,最終與純Python的速度大致相同(即實際上相當不錯)。

使用100個字符的長字節串( b'0'*100 )和10000次迭代timeit我得到:

  • 您編寫的代碼 - 0.37s
  • 您編寫的代碼,但在Cython中編譯 - 0.21s
  • 您的代碼使用行cdef int i並在Cython中編譯 - 0.20s(這是可重復的一個小改進。對於更長的字符串,它更重要)
  • 你的cdef int i和鍵入bytes text的參數bytes text - 0.28s(即更糟)。
  • 通過直接使用Python C API獲得最佳速度(參見下面的代碼) - 0.11s。 為了方便起見,我選擇在Cython(但是自己調用API函數)中這樣做,但你可以直接在C中編寫非常相似的代碼,並進行更多的手動錯誤檢查。 我寫這一個為Python 3 API假設你使用的字節對象(即PyBytes代替PyString ),所以如果你正在使用Python 2,或Unicode和Python 3,你必須改變它一點。

     from cpython cimport * cdef extern from "Python.h": # This isn't included in the cpython definitions # using PyObject* rather than object lets us control refcounting PyObject* Py_BuildValue(const char*,...) except NULL def split(text): cdef Py_ssize_t l,i cdef char* s # Cython automatically checks the return value and raises an error if # these fail. This provides a type-check on text PyBytes_AsStringAndSize(text,&s,&l) output = PyList_New(l) for i in range(l): # PyList_SET_ITEM steals a reference # the casting is necessary to ensure that Cython doesn't # decref the result of Py_BuildValue PyList_SET_ITEM(output,i, <object>Py_BuildValue('y#y#',s,i+1,s+i+1,l-(i+1))) return output 
  • 如果你不想一直使用C API那么預先分配列表output = [None]*len(text)的版本output = [None]*len(text)並執行for循環而不是列表理解比你的更有效率原始版本 - 0.18s

總之,只需在Cython中編譯它就可以獲得相當快的速度(略低於2倍)並且設置i的類型有點幫助。 這是您通過常規方式實現的所有功能。 要獲得全速,您基本上需要直接使用Python C API。 這讓你速度提高了4倍,我認為這相當不錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM