4

私はバイトの文字列 (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 を使用すると、実行時間が ~.33 秒になりましたが、これにより、10 倍速くなり、 ~.03 秒になりました (どちらも 1.5​​ MB を超える圧縮された巨大な文字列で実行されました)。

パフォーマンスの向上はごくわずかですが、これを行うためのより良い方法はありますか?

(フィルタリングされた文字列を保存する方がはるかに最適であることは承知しています。ただし、これはオプションではありません。Minecraft クラシック サーバーのレベル形式をだましていて、特定のクライアントがサポートしていないバイトを除外する必要があります。 )

4

3 に答える 3

4

文字列のtranslate()メソッドを調べます。これにより、文字列の 1 回のパスで任意の数の 1 バイト変換を実行できます。関数を使用しstring.maketrans()て変換テーブルを作成します。通常 16 ペアの場合、これは 1 バイト置換を 16 回行うよりも約 16 倍速く実行されるはずです。

于 2013-09-17T03:30:13.200 に答える
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 文字列はデザイン内で不変であるため、置換ごとに新しい文字列が作成されます。

これはすべて推測に基づくものであり、間違っている可能性があります。実際のデータでテストする必要があります。

于 2013-09-17T03:29:18.793 に答える