我的代码分析显示方法 split
和strip
的str
对象是最常被调用的函数之一。
我碰巧使用了这样的结构:
with open(filename, "r") as my_file:
for line in my_file:
fields = line.strip("\n").split("\t")
应用此功能的一些文件有很多行。
所以我尝试使用 https://wiki.python.org/moin/PythonSpeed/PerformanceTips 中的“避免点”建议如下:
from functools import partial
split = str.split
tabsplit = partial(split, "\t")
strip = str.strip
endlinestrip = partial(strip, "\n")
def get_fields(tab_sep_line):
return tabsplit(endlinestrip(tab_sep_line))
with open(filename, "r") as my_file:
for line in my_file:
fields = getfields(line)
但是,这给了我一个 ValueError: empty separator
对于return
我的线get_fields
功能。
经过调查,我了解到 split
的分隔符方法是第二个位置参数,第一个是字符串对象本身,这使得 functools.partial
了解"\t"
作为要分割的字符串,我使用 "\n".strip(tab_sep_line)
的结果作为分隔符。因此出现错误。
您建议做什么?
<小时/>编辑:
我尝试比较三种实现 get_fields
的方法功能。
方法 1:使用普通 .strip
和.split
def get_fields(tab_sep_line):
return tab_sep_line.strip("\n").split("\t")
方法 2:使用 lambda
split = str.split
strip = str.strip
tabsplit = lambda s : split(s, "\t")
endlinestrip = lambda s : strip(s, "\n")
def get_fields(tab_sep_line):
return tabsplit(endlinestrip(tab_sep_line))
方法 3:使用 Jason S 提供的答案
split = str.split
strip = str.strip
def get_fields(tab_sep_line):
return split(strip(tab_sep_line, "\n"), "\t")
分析表明 get_fields
的累积时间如下:
方法 1:13.027
方法 2:16.487
方法 3:9.714
因此,避免点会有所不同,但使用 lambda
似乎适得其反。
最佳答案
“避免点”以提高性能的建议是(1)只有当您确实遇到性能问题时才应该这样做,即不是如果它只是被调用了很多次而是如果它实际上花费了太多时间,并且 (2) 无法通过使用 partial
来解决。
点比本地花费更多时间的原因是Python每次都必须执行查找。但如果您使用 partial
,那么每次和都会有一个额外的函数调用,并且每次和添加两个列表时它还会复制和更新字典。你没有得到,你正在失去。
但是,如果您确实愿意,可以这样做:
strip = str.strip
split = str.split
...
fields = split(strip(line), '\t')
关于python - 将 functools.partial 与字符串方法一起使用的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25220280/