0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】`in list`を`in set`に変えたら2985倍速くなった話

0
Last updated at Posted at 2026-02-28

in listをin setに変えたら2985倍速くなった話。Pythonで最初に直すべき3箇所

アルゴリズムの改造も、並列化も不要。書き方を1行変えるだけで、笑えない倍率が出ました。


先に結果を見てください

改善項目 最大速度向上
in list → in set 2985倍
list.insert(0, i) → deque.appendleft(i) 381倍
文字列 += → "".join() 8.7倍

数字がちょっと笑えないレベルなので、計測結果ごと残しておきます。


本記事のリポジトリ


1. in list → in set(最大 2985倍)

# Before
found = target in list_data   # O(n) — 先頭から1件ずつ線形探索

# After
found = target in set_data    # O(1) — ハッシュで一発

なぜ差が出るか

データ構造 探索方法 計算量
list 先頭から1件ずつ比較 O(n)
set ハッシュテーブルで直接参照 O(1)

listはデータが10倍になれば探索も10倍遅くなります。setはデータ量が増えてもほぼ一定です。

if x in some_list という書き方はどのコードにも必ずあるので、ここを直すだけでも体感が変わることがあります。


2. list.insert(0, i) → deque.appendleft(i)(最大 381倍)

# Before
items = []
for i in range(n):
    items.insert(0, i)        # 追加のたびに全要素を後ろへシフト

# After
from collections import deque
items = deque()
for i in range(n):
    items.appendleft(i)       # 両端操作が O(1)

なぜ差が出るか

list.insert(0, ...) は先頭に1件追加するたびに、それ以降の全要素を1つ後ろにずらします。要素数が増えるほど、その移動コストも増えるため、全体では O(n²) になります。

deque(双方向キュー)は先頭・末尾への追加・削除がどちらも O(1) です。

キューのような処理を list で書いているコードがあれば、ほぼ確実にここが詰まっています。インターフェースはほぼ変わらず、数字だけ変わります。


3. 文字列 += → "".join()(最大 8.7倍)

# Before
result = ""
for p in parts:
    result += p               # ループのたびに新しいstr オブジェクトを生成

# After
result = "".join(parts)      # 必要サイズを計算してから1回で結合

なぜ差が出るか

Pythonの文字列は**イミュータブル(変更不可)**です。+= をするたびに「古い文字列 + 新しい文字列」のコピーを毎回作り直すため、ループが増えるほどメモリ確保とコピーが積み上がります。

join() は事前に合計サイズを計算して、メモリを1回だけ確保してから結合するため高速です。

倍率は上2つと比べると小さく見えますが、ループ回数が多いコードでは確実に効いてきます。


まとめ:今すぐ確認すべき3箇所

# 直す前 直した後 効く場面
1 x in list x in set 検索を繰り返すとき
2 list.insert(0, x) deque.appendleft(x) 先頭への追加を繰り返すとき
3 ループ内の += "".join() 文字列を連結し続けるとき

いずれも「アルゴリズムを変える」のではなく、データ構造と組み込み関数の使い方を変えるだけです。既存コードへの影響も最小限なので、まず探してみてください。


計測条件

  • 計測ライブラリ:timeit
  • 実行設定:number=10、repeat=5、最小値採用
  • データサイズ:N = 10,000 / 30,000 / 50,000
python3 benchmark.py --sizes 10000,30000,50000 --number 10 --repeat 5

詳細な計測結果は benchmark_results.txt を参照してください。


リポジトリ(スターをもらえると喜びます)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?