有没有一种方法可以在Python 2中使用带有正则表达式的memoryview?

埃里克·普鲁特(Eric Pruitt)

在Python 3中,该re模块可以与一起使用memoryview

~$ python3
Python 3.2.3 (default, Feb 20 2013, 14:44:27)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x = b"abc"
>>> import re
>>> re.search(b"b", memoryview(x))
<_sre.SRE_Match object at 0x7f14b5fb8988>

但是,在Python 2中,情况似乎并非如此:

~$ python
Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x = "abc"
>>> import re
>>> re.search(b"b", memoryview(x))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/re.py", line 142, in search
    return _compile(pattern, flags).search(string)
TypeError: expected string or buffer

我可以将字符串转换为a buffer,但是在缓冲区文档中,它没有确切地提到buffer与a相比是如何工作的memoryview

进行经验比较表明,buffer在Python 2中使用对象不能提供memoryview在Python 3中使用对象的性能优势

playground$ cat speed-test.py
import timeit
import sys

print(timeit.timeit("regex.search(mv[10:])", setup='''
import re
regex = re.compile(b"ABC")
PYTHON_3 = sys.version_info >= (3, )
if PYTHON_3:
    mv = memoryview(b"Can you count to three or sing 'ABC?'" * 1024)
else:
    mv = buffer(b"Can you count to three or sing 'ABC?'" * 1024)
'''))
playground$ python2.7 speed-test.py
2.33041596413
playground$ python2.7 speed-test.py
2.3322429657
playground$ python3.2 speed-test.py
0.381270170211792
playground$ python3.2 speed-test.py
0.3775448799133301
playground$

如果将regex.search参数从更改mv[10:]mv,则Python 2的性能与Python 3的性能大致相同,但是在我编写的代码中,有很多重复的字符串切片。

有没有一种方法可以在Python 2中规避此问题,同时仍然具有零复制性能的好处memoryview

据我了解Python 2中缓冲区对象的方式,您应该在不切片的情况下使用它:

>>> s = b"Can you count to three or sing 'ABC?'"
>>> str(buffer(s, 10))
"unt to three or sing 'ABC?'"

因此,无需切片结果缓冲区,而是直接使用buffer函数执行切片,从而可以快速访问您感兴趣的子字符串:

import timeit
import sys
import re

r = re.compile(b'ABC')
s = b"Can you count to three or sing 'ABC?'" * 1024

PYTHON_3 = sys.version_info >= (3, )
if len(sys.argv) > 1: # standard slicing
    print(timeit.timeit("r.search(s[10:])", setup='from __main__ import r, s'))
elif PYTHON_3: # memoryview in Python 3
    print(timeit.timeit("r.search(s[10:])", setup='from __main__ import r, s; s = memoryview(s)'))
else: # buffer in Python 2
    print(timeit.timeit("r.search(buffer(s, 10))", setup='from __main__ import r, s'))

我在Python 2和3中获得了非常相似的结果,这表明bufferre模块一起使用类似的效果与较新模块memoryview(后者似乎是延迟计算的缓冲区)相似

$ python2 .\speed-test.py
0.681979371561
$ python3 .\speed-test.py
0.5693422508853488

并与标准字符串切片进行比较:

$ python2 .\speed-test.py standard-slicing
7.92006735956
$ python3 .\speed-test.py standard-slicing
7.817641705304309

如果要支持切片访问(以便可以在任何地方使用相同的语法),则可以轻松创建一个在切片时动态创建新缓冲区的类型:

class slicingbuffer:
    def __init__ (self, source):
        self.source = source
    def __getitem__ (self, index):
        if not isinstance(index, slice):
            return buffer(self.source, index, 1)
        elif index.stop is None:
            return buffer(self.source, index.start)
        else:
            end = max(index.stop - index.start, 0)
            return buffer(self.source, index.start, end)

如果仅将其与re模块一起使用,它可能会直接替代memoryview但是,我的测试表明,这已经给您带来了巨大的开销。因此,您可能想做相反的事情,并将Python 3的memoryview对象包装在一个包装器中,该包装器为您提供与以下相同的接口buffer

def memoryviewbuffer (source, start, end = -1):
    return source[start:end]

PYTHON_3 = sys.version_info >= (3, )
if PYTHON_3:
    b = memoryviewbuffer
    s = memoryview(s)
else:
    b = buffer

print(timeit.timeit("r.search(b(s, 10))", setup='from __main__ import r, s, b'))

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

有没有办法在Python 2中使用带有正则表达式的memoryview?

来自分类Dev

有没有一种方法可以在Python中使用if语句生成“ Not a number”?

来自分类Dev

有没有一种方法可以简化正则表达式匹配字符?

来自分类Dev

Python中有没有一种方法可以创建在正则表达式中匹配的组件的元组?

来自分类Dev

有没有一种方法可以在Python中禁用数组边界检查?

来自分类Dev

有没有一种方法可以检查函数是否在python中是递归的?

来自分类Dev

有没有一种方法可以在Windows上的python中运行命令?

来自分类Dev

有没有一种方法可以比较python中枚举的内容?

来自分类Dev

有没有一种方法可以在Python中实现全局计算属性?

来自分类Dev

有没有一种方法可以加快python中的嵌套for循环?

来自分类Dev

有没有一种方法可以在python库pywhatkit中定义变量?

来自分类Dev

有没有一种方法可以简化Python中的“循环” /“循环”交互?

来自分类Dev

有没有一种方法可以在Python中为文本着色?

来自分类Dev

有没有一种方法可以使用Python从目录创建jar?

来自分类Dev

有没有一种方法可以缩进Python而不会影响代码

来自分类Dev

Python模板,有没有一种方法可以从多个html文件继承?

来自分类Dev

Python:有没有一种方法可以漂亮地打印列表?

来自分类Dev

有没有一种方法可以直接“装饰” Python代码块?

来自分类Dev

有没有一种方法可以使Python列表需要某个对象?

来自分类Dev

有没有一种方法可以将列表放入Python集?

来自分类Dev

Python模板,有没有一种方法可以从多个html文件继承?

来自分类Dev

有没有一种方法可以直接“装饰” Python代码块?

来自分类Dev

有没有一种方法可以只替换Java匹配器正则表达式中的一个捕获组?

来自分类Dev

有没有一种方法可以删除没有实时CD的g

来自分类Dev

有没有一种方法可以让iOS的自动更正忽略UITextView中的单个单词或正则表达式?

来自分类Dev

有没有一种方法可以形成此正则表达式,以使可选组不会出现在匹配组中?

来自分类Dev

有没有一种方法可以保存带有参数的函数调用?

来自分类Dev

有没有一种方法可以保存带有参数的函数调用?

来自分类Dev

有没有一种方法可以在python中为类的所有实例运行方法?

Related 相关文章

  1. 1

    有没有办法在Python 2中使用带有正则表达式的memoryview?

  2. 2

    有没有一种方法可以在Python中使用if语句生成“ Not a number”?

  3. 3

    有没有一种方法可以简化正则表达式匹配字符?

  4. 4

    Python中有没有一种方法可以创建在正则表达式中匹配的组件的元组?

  5. 5

    有没有一种方法可以在Python中禁用数组边界检查?

  6. 6

    有没有一种方法可以检查函数是否在python中是递归的?

  7. 7

    有没有一种方法可以在Windows上的python中运行命令?

  8. 8

    有没有一种方法可以比较python中枚举的内容?

  9. 9

    有没有一种方法可以在Python中实现全局计算属性?

  10. 10

    有没有一种方法可以加快python中的嵌套for循环?

  11. 11

    有没有一种方法可以在python库pywhatkit中定义变量?

  12. 12

    有没有一种方法可以简化Python中的“循环” /“循环”交互?

  13. 13

    有没有一种方法可以在Python中为文本着色?

  14. 14

    有没有一种方法可以使用Python从目录创建jar?

  15. 15

    有没有一种方法可以缩进Python而不会影响代码

  16. 16

    Python模板,有没有一种方法可以从多个html文件继承?

  17. 17

    Python:有没有一种方法可以漂亮地打印列表?

  18. 18

    有没有一种方法可以直接“装饰” Python代码块?

  19. 19

    有没有一种方法可以使Python列表需要某个对象?

  20. 20

    有没有一种方法可以将列表放入Python集?

  21. 21

    Python模板,有没有一种方法可以从多个html文件继承?

  22. 22

    有没有一种方法可以直接“装饰” Python代码块?

  23. 23

    有没有一种方法可以只替换Java匹配器正则表达式中的一个捕获组?

  24. 24

    有没有一种方法可以删除没有实时CD的g

  25. 25

    有没有一种方法可以让iOS的自动更正忽略UITextView中的单个单词或正则表达式?

  26. 26

    有没有一种方法可以形成此正则表达式,以使可选组不会出现在匹配组中?

  27. 27

    有没有一种方法可以保存带有参数的函数调用?

  28. 28

    有没有一种方法可以保存带有参数的函数调用?

  29. 29

    有没有一种方法可以在python中为类的所有实例运行方法?

热门标签

归档