仕事のネタで、Python3(Django)の設定ファイルをreloadしたい、というのがあります。
つまり設定ファイルをちょこちょこ変更するが、その変更のたびにサービスをリスタートするのではなく設定ファイルを変更したら、その変更をダイレクトに読み取って処理したいとのこと。
で、問題は、それはをするとやたら遅くなる
ことになります。
なんせリクエストごとに何回も読み取って、何回も処理することになるので。
それは嫌なので、なんとか高速化します。が、そもそもどんな感じの処理速度感なのかを調べてみました。
環境
- WSL2 (Windows 10)
- Python3.12.3
- PyYAML(6.0.1)
- Pickle/JSON (include PYthon3)
調査内容
調査内容はJSON/YAML/Pickleにて、あるデータ(辞書)を10000回読み書きし、その秒数を計測します。
ソース
ソースは以下の感じです。ちなみに、ほぼMicrosoft Egge Copilot(生成AI)産です。
import json
import yaml
import pickle
import time
# サンプルデータ
data = {'name': 'Copilot', 'age': 1, 'languages': ['Python', 'JavaScript', 'Bash']}
iterations = 10000
# JSONでの書き込みと読み込みの時間測定
json_write_time = 0
json_read_time = 0
for _ in range(iterations):
start_time = time.time()
with open('data.json', 'w') as json_file:
json.dump(data, json_file)
json_write_time += time.time() - start_time
start_time = time.time()
with open('data.json', 'r') as json_file:
data_loaded_json = json.load(json_file)
json_read_time += time.time() - start_time
# YAMLでの書き込みと読み込みの時間測定
yaml_write_time = 0
yaml_read_time = 0
for _ in range(iterations):
start_time = time.time()
with open('data.yaml', 'w') as yaml_file:
yaml.dump(data, yaml_file)
yaml_write_time += time.time() - start_time
start_time = time.time()
with open('data.yaml', 'r') as yaml_file:
data_loaded_yaml = yaml.safe_load(yaml_file)
yaml_read_time += time.time() - start_time
# Pickleでの書き込みと読み込みの時間測定
pickle_write_time = 0
pickle_read_time = 0
for _ in range(iterations):
start_time = time.time()
with open('data.pkl', 'wb') as pickle_file:
pickle.dump(data, pickle_file)
pickle_write_time += time.time() - start_time
start_time = time.time()
with open('data.pkl', 'rb') as pickle_file:
data_loaded_pickle = pickle.load(pickle_file)
pickle_read_time += time.time() - start_time
# 結果の出力
print(f'JSON Write Time: {json_write_time}')
print(f'JSON Read Time: {json_read_time}')
print(f'YAML Write Time: {yaml_write_time}')
print(f'YAML Read Time: {yaml_read_time}')
print(f'Pickle Write Time: {pickle_write_time}')
print(f'Pickle Read Time: {pickle_read_time}')
結果
結果は以下のとおりです。本質的に、単位は関係なく、相対的な数値として見てください。
- JSON
- 書き込み: 3.47
- 読み込み: 0.40
- YAML
- 書き込み: 4.34
- 読み込み: 3.59
- Pickle
- 書き込み: 2.64
- 読み込み: 0.22
出力結果は以下のとおりです。
$ python3 ./datatime.py
JSON Write Time: 3.437263250350952
JSON Read Time: 0.4125795364379883
YAML Write Time: 4.31871771812439
YAML Read Time: 3.579468250274658
Pickle Write Time: 2.7502527236938477
Pickle Read Time: 0.21659040451049805
$ python3 ./datatime.py
JSON Write Time: 3.716987371444702
JSON Read Time: 0.42149829864501953
YAML Write Time: 4.308393239974976
YAML Read Time: 3.5967061519622803
Pickle Write Time: 2.6990926265716553
Pickle Read Time: 0.20854496955871582
$ python3 ./datatime.py
JSON Write Time: 3.2737653255462646
JSON Read Time: 0.39243149757385254
YAML Write Time: 4.3981523513793945
YAML Read Time: 3.5982000827789307
Pickle Write Time: 2.5000874996185303
Pickle Read Time: 0.24534940719604492
結論
重要なのは読み込み比率なので比率で出すと
JSON:YAML:Pickle = 0.40:3.59:0.22 = 1.00:8.97:0.55
ぐらいになります。
- JSONは安定的に早い
- YAMLは書くのはわかりやすくて良いがそのままだと読むのが遅い
- Pickleは早いが、人間が直接読み書きするのは無理。
このぐらいの比率ならJSONにしてもいいような気がします。
ただし、JSONは人が書くと確実に間違うのでチェック機構が必要で、
チェックするならデータとしてPickleで書き出してもいいような気がします。
そこら辺は迷うところですね。。
終わりに
やはり計測は必要だ、と思いました。