[英]Fastest way to substitute a set of characters in a string
我正在使用一串字節(可以是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服務器的級別格式,並且必須過濾掉某些客戶端不支持的字節)
使用str.translate
:
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)
在字符串上查找translate()
方法。 這允許您在字符串上的一次傳遞中進行任意數量的1字節轉換。 使用string.maketrans()
函數構建轉換表。 如果你通常有16對,這比16字節替換1字節要快16倍。
在您當前的設計中, 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字符串在你的設計中是不可變的,因此每個替換都會生成一個新的字符串。
這完全基於猜想,可能是錯誤的。 您需要使用實際數據進行測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.