🐍

[Python] フォーマット済み文字列リテラルとformat()メソッドを組み合わせる

2022/06/06に公開

はじめに

フォーマット済み文字列とformat()メソッドを組み合わせると効率が良い場合もあるのではないかと思い試してみました。
分かってしまえば単純なのですが、答えにたどり着くまでに悩んだので記事にしてみます。
あまり実用的でもない感じですが。

環境

python
Python 3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]

コード

下記のようなコードあるとします。
書式指定文字列部分(jの値)は、起動時には決まるとします。
そうすると、毎回ループ内で作成していると効率が悪い事になります。
まあ、下記の例だと大したことはありませんが、もっと露骨に聞いてくる場面もあるかもしれません。

j = 4
for i in range(1000):
  print(f"{i:>0{j}X}")

そこで、jの値が影響する部分を事前に作成しておくことにします。
オリジナルは、下記と同等になります。
(フォーマット済み文字列内で、{}を表すには、{{}}します。)

同等1
print(f"{{:>0{j}X}}".format(i))

こうなると、下記の様に表せます。

同等2
fs = f"{{:>0{j}X}}"
print(fs.format(i))

実行時間の計測

実行時間の計測
import timeit
import gc

def test1():
  j = 4
  for i in range(100):
    string = f"{i:>0{j}X}"

def test2(fs):
  j = 4
  for i in range(100):
    string = fs.format(i)


r = 10
n = 10000
j = 4
fs = f"{{:>0{j}X}}"
result1 = timeit.repeat(lambda: test1(), gc.collect, repeat=r, number=n)
result2 = timeit.repeat(lambda: test2(fs), gc.collect, repeat=r, number=n)
print(list(map(lambda x, y: x - y, result2, result1)))

確実に差はあるようです。

実行時間
[-0.04442920000292361, -0.0421675999823492, -0.04588760000478942, -0.042600400003721006, -0.03534270000818651, -0.05360689999361057, -0.044703200008370914, -0.05354990001069382, -0.048129000002518296, -0.044385700006387196]

Discussion