【要約】DRF 一覧 Serializer が重い — Field compile と PyO3 batch を試して分かったこと [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
開発者がDRFを用いて大量のデータを一覧取得する際、Serializerの処理がボトルネックとなりレイテンシが悪化する問題に直面した。
- ・cProfileにより
to_representationが累積時間の主要因と判明。 - ・1行ごとに発生する
get_attributeのオーバーヘッドが致命的。 - ・N+1問題は解消済みであることを前提とした、Serializer層の遅延。
- ・Rustによる属性アクセス高速化だけでは、PyO3の境界コストにより不十分。
// Approach
筆者は、DRFのField定義を事前にコンパイルし、データを列単位(Columnar)で扱う手法を検討した。
- ・PyO3を用いてRustで属性アクセスを高速化する試行。
- ・Field定義をコンパイルし、固定getterで値を読み取る手法。
- ・Columnar化したデータをPyO3で一括してdict化する手法。
- ・dictを経由せず、Rustで直接JSON bytesを生成する手法。
- ・これら複数の手法を段階的に適用し、ボトルネックを定量的に分析した。
// Result
検証の結果、Field compileによるデータ抽出の効率化が最も高い効果を示した。
- ・Field compile + PyO3 dict により、DRF比で約3.1倍の高速化を達成。
- ・JSON bytes直出しは、dict経由と比較して3%程度の改善に留まった。
- ・ボトルネックはデータ抽出(Pass 1)にあり、変換(Pass 2)の最適化だけでは不十分。
- ・手書きのPython dictループと比較すると、依然として数倍の差が存在する。
Senior Engineer Insight
> 性能改善の優先順位を誤ると、開発コストに見合う成果が得られない。本記事は、Rustによるネイティブ化を急ぐ前に、Field compileによるデータ抽出の効率化を優先すべきだと示唆している。DRFの定義を維持しつつ3倍の改善が見込める点は実用的だ。ただし、SerializerMethodFieldが非対応である点や、運用コストの増大には注意が必要である。