最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中判斷子串存在的性能比較及分析總結(jié)

 更新時間:2019年06月23日 08:40:03   作者:棲遲于一丘  
這篇文章主要給大家總結(jié)介紹了Python中判斷子串存在的性能比較及分析的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

起步

對于子串搜索,Python提供了多種實現(xiàn)方式:in, find, index, __contains__,對其進行性能比較:

import timeit

def in_(s, other):
  return other in s

def contains(s, other):
  return s.__contains__(other)

def find(s, other):
  return s.find(other) != -1

def index(s, other):
  try:
    s.index(other)
  except ValueError:
    return False
  return True

perf_dict = {
  'in:True': min(timeit.repeat(lambda: in_('superstring', 'str'))),
  'in:False': min(timeit.repeat(lambda: in_('superstring', 'not'))),
  '__contains__:True': min(timeit.repeat(lambda: contains('superstring', 'str'))),
  '__contains__:False': min(timeit.repeat(lambda: contains('superstring', 'not'))),
  'find:True': min(timeit.repeat(lambda: find('superstring', 'str'))),
  'find:False': min(timeit.repeat(lambda: find('superstring', 'not'))),
  'index:True': min(timeit.repeat(lambda: index('superstring', 'str'))),
  'index:False': min(timeit.repeat(lambda: index('superstring', 'not'))),
}

print(perf_dict)

得到結(jié)果:

{
    'in:True': 0.2763608000000001,
    'in:False': 0.2794432,
    '__contains__:True': 0.40546490000000013,
    '__contains__:False': 0.4122471000000001,
    'find:True': 0.497128,
    'find:False': 0.4951530000000002,
    'index:True': 0.5243821999999998,
    'index:False': 0.8693923999999988
}

從結(jié)果上 in 的搜索方式性能上最好。

知其然也要之其所以然,下面就對于這個結(jié)果進行比較與分析。

in 與 __contains__ 比較

了解 Python 中協(xié)議的應(yīng)該知道,in 操作其實也是調(diào)用 __contains__ ,但為什么 in 比 __contains__ 明顯快了很多,明明它們最終調(diào)用的C語言函數(shù)是一樣的。

在 CPython 中,in 屬于操作符,它直接指向了 sq_contains 中的C級函數(shù)指針,而在 str 中的 sq_contains 直接指向了最終調(diào)用的C層函數(shù)。而 __contains__ 的調(diào)用方式,則需要先在 str 屬性中進行 LOAD_ATTR 查找,然后再為 CALL_FUNCTION 創(chuàng)建函數(shù)調(diào)用所需的空間。

也就是說,in 直接指向了最終的C層函數(shù),一步到位,也不走Python虛擬機的函數(shù)調(diào)用,而 __contains__ 調(diào)用方式先屬性查找和Python函數(shù)調(diào)用的開銷;所以 str.__contains__(other) 的形式要慢得多。

一般來說,in 方式更快只使用 Python 內(nèi)置的C實現(xiàn)的類。對于用戶自定義類,因為最終調(diào)用都是Python級的,所以兩種方式都要對函數(shù)調(diào)用所需的空間的。

find 與 index 的比較

find 與 index 的查找方式的區(qū)別僅僅只是 index 在子串不存在時會拋出異常。從源碼來看:

static PyObject *
unicode_find(PyObject *self, PyObject *args)
{
  /* initialize variables to prevent gcc warning */
  PyObject *substring = NULL;
  Py_ssize_t start = 0;
  Py_ssize_t end = 0;
  Py_ssize_t result;

  if (!parse_args_finds_unicode("find", args, &substring, &start, &end))
    return NULL;

  if (PyUnicode_READY(self) == -1)
    return NULL;

  result = any_find_slice(self, substring, start, end, 1);

  if (result == -2)
    return NULL;

  return PyLong_FromSsize_t(result);
}

static PyObject *
unicode_index(PyObject *self, PyObject *args)
{
  /* initialize variables to prevent gcc warning */
  Py_ssize_t result;
  PyObject *substring = NULL;
  Py_ssize_t start = 0;
  Py_ssize_t end = 0;

  if (!parse_args_finds_unicode("index", args, &substring, &start, &end))
    return NULL;

  if (PyUnicode_READY(self) == -1)
    return NULL;

  result = any_find_slice(self, substring, start, end, 1);

  if (result == -2)
    return NULL;

  if (result < 0) {
    PyErr_SetString(PyExc_ValueError, "substring not found");
    return NULL;
  }

  return PyLong_FromSsize_t(result);
}

實現(xiàn)方式基本相同,所以在子串存在的時候,兩者的性能一致;而當(dāng)子串不存在時,index 會設(shè)置異常,因此涉及異常棧的空間等異常機制,速度上也就慢了一些。

總結(jié)

in 的搜索方式性能最佳,可讀性也最好,屬最佳實踐。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。

擴展閱讀

https://stackoverflow.com/questions/38400370/why-in-is-faster-than-contains

相關(guān)文章

  • Python一行代碼識別車牌號碼實現(xiàn)示例詳解

    Python一行代碼識別車牌號碼實現(xiàn)示例詳解

    這篇文章主要為大家介紹了Python一行代碼識別車牌號碼實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Python打印不合法的文件名

    Python打印不合法的文件名

    這篇文章主要介紹了Python打印不合法的文件名,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下的相關(guān)資料
    2020-07-07
  • 關(guān)于python寫入文件自動換行的問題

    關(guān)于python寫入文件自動換行的問題

    今天小編就為大家分享一篇關(guān)于python寫入文件自動換行的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • pandas如何修改特定的值

    pandas如何修改特定的值

    這篇文章主要介紹了pandas如何修改特定的值問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • 如何使用Cython對python代碼進行加密

    如何使用Cython對python代碼進行加密

    這篇文章主要介紹了如何使用Cython對python代碼進行加密,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • Django JSONField的自動轉(zhuǎn)換思路詳解(django自定義模型字段)

    Django JSONField的自動轉(zhuǎn)換思路詳解(django自定義模型字段)

    如果想實現(xiàn)JSONField的自動轉(zhuǎn)換,可以使用Django REST framework的JSONField,或者自定義一個字段類并覆蓋from_db_value()和get_prep_value()方法來實現(xiàn)這個功能,這篇文章主要介紹了Django JSONField的自動轉(zhuǎn)換(django自定義模型字段)問題,需要的朋友可以參考下
    2023-06-06
  • Python中生成隨機密碼的多種超實用實例

    Python中生成隨機密碼的多種超實用實例

    隨機密碼生成器是一種常見的工具,用于生成強密碼,下面這篇文章主要給大家介紹了關(guān)于Python中生成隨機密碼的多種超實用實例,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • 深入理解Python虛擬機中字節(jié)(bytes)的實現(xiàn)原理及源碼剖析

    深入理解Python虛擬機中字節(jié)(bytes)的實現(xiàn)原理及源碼剖析

    在本篇文章當(dāng)中主要給大家介紹在?cpython?內(nèi)部,bytes?的實現(xiàn)原理、內(nèi)存布局以及與?bytes?相關(guān)的一個比較重要的優(yōu)化點——?bytes?的拼接,需要的可以參考一下
    2023-03-03
  • 在PyCharm中打包Python項目并將其運行到服務(wù)器上的方法(推薦)

    在PyCharm中打包Python項目并將其運行到服務(wù)器上的方法(推薦)

    在PyCharm中打包Python項目并運行到服務(wù)器上,主要步驟包括:創(chuàng)建并設(shè)置項目、編寫項目代碼、打包項目、配置服務(wù)器環(huán)境、上傳可執(zhí)行文件到服務(wù)器以及運行項目,通過這些步驟,可以將Python項目打包并部署到服務(wù)器上
    2024-11-11
  • Python 變量的創(chuàng)建過程詳解

    Python 變量的創(chuàng)建過程詳解

    這篇文章主要介紹了Python 變量的創(chuàng)建過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09

最新評論

普陀区| 南澳县| 宁海县| 上饶市| 刚察县| 黄大仙区| 衡山县| 泗水县| 宝山区| 洪洞县| 霍城县| 太谷县| 资阳市| 西华县| 彩票| 曲松县| 望奎县| 皋兰县| 抚顺市| 雷州市| 潞城市| 许昌市| 垫江县| 合水县| 皮山县| 呼图壁县| 左权县| 拜城县| 道真| 游戏| 兴安盟| 商丘市| 五常市| 治多县| 许昌市| 肃宁县| 怀集县| 班玛县| 喀喇| 临沂市| 文昌市|