簡體   English   中英

替換字符串中一組字符的最快方法

[英]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

Python 3.x

def subs(st):
    return st.translate(BYTE_REPLACE)

用法示例:

>>> subs('4567')
'\x07\x0c67'

Python 2.x

str.translate (Python 2)

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM