对我的代码的分析显示,str
对象的split
和strip
方法是调用最多的函数之一。
我使用了这样的结构:
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)
然而,这给了我get_fields
函数的return
行一个ValueError: empty separator
。
经过调查,我所理解的是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")
Profiling表示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')