我正在使用一串字节(可以是10kb到3MB之间的任何地方),我需要过滤掉大约16个字节(用其他字节替换它们)
目前我的功能有点像这样......
BYTE_REPLACE = {
52: 7, # first number is the byte I want to replace
53: 12, # while the second number is the byte I want to replace it WITH
}
def filter(st):
for b in BYTE_REPLACE:
st = st.replace(chr(b),chr(BYTE_REPLACE[b]))
return st
(为了这个问题,字节列表被解释)
使用map导致执行时间为〜.33s,而这导致〜。03s的快10倍(两者都在巨大的字符串上执行,压缩大于1.5MB)。
虽然任何性能提升都可以忽略不计,但还有更好的方法吗?
(我知道存储过滤后的字符串会更加优化。但这不是一个选项。我愚弄了Minecraft Classic服务器的级别格式,并且必须过滤掉某些客户端的字节不支持
答案 0 :(得分:5)
def subs(st):
return st.translate(BYTE_REPLACE)
使用示例:
>>> subs('4567')
'\x07\x0c67'
import string
k, v = zip(*BYTE_REPLACE.iteritems())
k, v = ''.join(map(chr, k)), ''.join(map(chr, v))
tbl = string.maketrans(k, v)
def subs(st):
return st.translate(tbl)
答案 1 :(得分:4)
在字符串上查找translate()
方法。这允许您在字符串上的一次传递中进行任意数量的1字节转换。使用string.maketrans()
函数构建转换表。如果你通常有16对,这比16次替换1字节要快16倍。
答案 2 :(得分:0)
在您当前的设计中,每个字符串String.replace()
次调用n
次。虽然它最有可能是一种高效算法,但在3MB字符串上它可能会变慢。
如果在调用此函数时字符串已经包含在内存中,我会打赌最有效的方法是:
BYTE_REPLACE = {
52: 7, # first number is the byte I want to replace
53: 12, # while the second number is the byte I want to replace it WITH
}
def filter(st):
st = list(st) # Convert string to list to edit in place :/
for i,s in enumerate(st): #iterate through list
if ord(s) in BYTE_REPLACE.keys():
s[i]=chr(BYTE_REPLACE[ord(b)])
return "".join(st) #return string
有一个很大的操作要在开始时创建一个新列表,另一个用于转换回字符串,但由于python字符串在您的设计中是不可变的,因此每个替换都会生成一个新字符串。
这完全基于猜想,可能是错误的。您需要使用实际数据进行测试。