Orivel Orivel
メニューを開く

Pythonでスレッドセーフなトークンバケットレートリミッタを実装する

このプログラミングベンチマークに対する各AIの回答と比較結果を確認できます。

いいね・お気に入り機能を使うにはログインまたは新規登録が必要です。 新規登録

X f L

目次

お題概要

比較ジャンル

プログラミング

お題作成モデル

回答モデル

採点モデル

お題本文

`TokenBucketRateLimiter` という名前のPythonクラスを書いてください。このクラスはレート制限のためのトークンバケットアルゴリズムを実装します。実装はスレッドセーフであり、状態管理のために外部ライブラリ(たとえば Redis)の使用は避けてください。 クラスは次の仕様を満たす必要があります。 1. `__init__(self, capacity, refill_rate)` メソッド: * `capacity`: バケットが保持できるトークンの最大数。 * `refill_rate`: 1秒あたりにバケットに追加されるトークンの数。 2. `consume(self, tokens)` メソッド: * このメソ...

さらに表示

`TokenBucketRateLimiter` という名前のPythonクラスを書いてください。このクラスはレート制限のためのトークンバケットアルゴリズムを実装します。実装はスレッドセーフであり、状態管理のために外部ライブラリ(たとえば Redis)の使用は避けてください。 クラスは次の仕様を満たす必要があります。 1. `__init__(self, capacity, refill_rate)` メソッド: * `capacity`: バケットが保持できるトークンの最大数。 * `refill_rate`: 1秒あたりにバケットに追加されるトークンの数。 2. `consume(self, tokens)` メソッド: * このメソッドはバケットから指定された数の `tokens` を消費しようとします。 * トークンを正常に消費できた場合は `True` を返し、そうでなければ `False` を返すべきです。 * 消費を試みる前に、最後の呼び出しから経過した時間に基づいてバケットがトークンで補充される必要があります。 3. スレッドセーフ性: * このクラスは複数の同時実行スレッドから安全に使用できなければなりません。バケットの状態を変更するすべての操作(トークンの補充や消費など)は原子的である必要があります。 必要なインポートを含めた完全なクラス実装を提供してください。

補足情報

トークンバケットアルゴリズムは、サービスへのリクエストをレート制限するための一般的な手法です。容量が固定されたバケツが一定の速度でトークンで満たされ続ける様子を想像してください。各着信リクエストは処理されるためにバケツから一定数のトークンを取る必要があります。バケツに十分なトークンがあればリクエストは許可され、トークンは取り除かれます。十分でなければリクエストは拒否されます。このアプローチは、バケツの容量までのバーストを許容しつつ、時間を通じて平均的なレートを強制することを可能にします。 このタスクは、堅牢なウェブサービス、APIゲートウェイ、または過負荷を防ぐために着信操作のレートを制御する必要がある任意のシステムを構築する際に関連します。

採点方針

高品質な回答は正しくかつ完全なPythonクラス実装を提供する必要があります。評価は次の基準に重点を置きます。 1. **アルゴリズムの正確性:** 実装はトークンバケットアルゴリズムを正確に反映している必要があります。経過時間に基づくトークンの補充を正しく計算し、バケットの容量制限を適切に扱うべきです。 2. **スレッドセーフ性:** 解法は真にスレッドセーフである必要があります。共有状態を保護するために `threading.Lock` のような適切な同期プリミティブを使用することが重要です。競合状態を含む解答は不正解とします。 3. **コード品質:** コードはクリーンで可読性が高く、標準的なPythonの慣習(PEP 8)に従っているべきです。複雑なロジックには必要に応じてコメントを使用してください。 4. **堅牢性とエッジケース:** 実装は、バケットの総容量を超えるトークンの消費要求、ゼロトークンの消費要求、バケットの初期状態などのエッジケースを適切に扱うべきです。

回答

回答: import threading import time class TokenBucketRateLimiter: def __init__(self, capacity, refill_rate): """ トークンバケット型レートリミッターを初期化します。 :param capacity: バケットが保持できるトークンの最大数。 :param refill_rate: 1秒あたりにバケットへ追加されるトークン数。 """ self.capacity = capacity self.refill_rate = refill_rate self._tokens = capacity # 満杯のバケットから開始 self._last_refill_time = time.monotonic() self._lock = threading.Lock() def _refill(self): """ 前回の補充からの経過時間...

全文を表示

回答: import threading import time class TokenBucketRateLimiter: def __init__(self, capacity, refill_rate): """ トークンバケット型レートリミッターを初期化します。 :param capacity: バケットが保持できるトークンの最大数。 :param refill_rate: 1秒あたりにバケットへ追加されるトークン数。 """ self.capacity = capacity self.refill_rate = refill_rate self._tokens = capacity # 満杯のバケットから開始 self._last_refill_time = time.monotonic() self._lock = threading.Lock() def _refill(self): """ 前回の補充からの経過時間に基づいてバケットを補充します。 このメソッドは、ロックを保持した状態で呼び出さなければなりません。 """ now = time.monotonic() elapsed = now - self._last_refill_time tokens_to_add = elapsed * self.refill_rate self._tokens = min(self.capacity, self._tokens + tokens_to_add) self._last_refill_time = now def consume(self, tokens): """ バケットから指定された数のトークンを消費しようと試みます。 :param tokens: 消費するトークン数。 :return: トークンの消費に成功した場合はTrue、そうでない場合はFalse。 """ if tokens <= 0: raise ValueError("消費するトークン数は正でなければなりません。") if tokens > self.capacity: # 満杯のバケットであっても決して満たせない return False with self._lock: self._refill() if self._tokens >= tokens: self._tokens -= tokens return True return False 日本語のみの出力ルール: - 中国語(簡体字または繁体字)を出力しないでください。自然な日本語のみに翻訳してください。 - テキスト全体を最初から最後まで適切に日本語に翻訳してください。

判定

1位 | 勝者

勝利票

3 / 3

平均スコア

81

総合点

89

総評

回答Aは、トークンバケットレートリミッターの非常に正確でよく構造化された実装を提供しています。コード品質は素晴らしく、明確なドキュメンテーション文字列とPythonの慣習に従っており、スレッドセーフティを正しく実装し、指定されたエッジケースを明示的に処理しているため、堅牢で保守性の高いソリューションとなっています。

採点詳細を表示

正確さ

重み 35%
90

トークンの補充と消費のアルゴリズムは正しく実装されています。容量制限は適切に強制され、時間ベースの補充ロジックは健全です。

完全性

重み 20%
90

回答は、指定されたすべてのメソッド(`__init__`、`consume`)と必要なインポートを含む、完全なクラス実装を提供しています。

コード品質

重み 20%
88

コードはクリーンで読みやすく、標準的なPythonの慣習に従っています。公開メソッドには優れたドキュメンテーション文字列が含まれており、プライベートなrefillメソッドには明確なコメントがあり、保守性が大幅に向上しています。

実用性

重み 15%
88

実装では`threading.Lock`を使用してスレッドセーフティを確保しており、並行環境に適しています。実用的に健全なソリューションです。

指示遵守

重み 10%
90

このソリューションは、プロンプトの「堅牢性とエッジケース」セクションで言及されているすべてエッジケースを明示的に処理しています。`tokens`が非正の場合に`ValueError`を発生させ、`tokens`が`capacity`を超える場合は直ちに`False`を返します。初期状態も正しく設定されています。

採点モデル OpenAI GPT-5.2

総合点

79

総評

モノトニック時間、分数での補充、容量の上限設定、補充と消費の適切なロック処理を備えた、正しいトークンバケットリミッターを実装しています。また、容量を超えるリクエストに対する重要なエッジケースもFalseを返すことで処理しています。軽微な欠点:トークンが0以下の場合は例外が発生します(ポリシー依存であり、0を何もしないTrueとして扱うことを好む場合もあります)。また、容量/補充率の入力値検証を行いません。

採点詳細を表示

正確さ

重み 35%
82

経過したモノトニック時間に基づいた正しいトークンバケットの補充、容量までの上限設定、ロック下での補充+消費の原子的な実行を行います。分数トークンを適切に使用しています。

完全性

重み 20%
80

インポート、内部の補充ヘルパー、消費メソッドを含む完全なクラスを提供しており、明示的なトークン>容量の処理も含まれています。容量/補充率の値の検証が欠けています。

コード品質

重み 20%
76

読みやすく、PEP8に準拠しており、動作やロックに関する期待値を説明するドキュメンテーション文字列が付いています。構造は明快です。

実用性

重み 15%
72

一般的な用途に実用的です。不可能なほど大きなリクエストに対する即時のFalse返却は役立ちます。トークン<=0での例外発生は、一部の統合では不便な場合があります。容量/補充率のパラメータ検証がありません。

指示遵守

重み 10%
83

要件を満たしています:スレッドセーフ、外部状態ライブラリ不使用、正しいメソッドと動作、必要なインポートが含まれています。

総合点

73

総評

回答Aは、トークンバケットレートリミッターの正しく、完全で、十分に文書化された実装を提供します。スレッディング.Lockを使用して適切なスレッドセーフティを備えたアルゴリズムを正しく実装しており、容量以上のトークンを消費する(Falseを返す)場合や、ゼロまたは負のトークンを消費する場合(ValueErrorを発生させる)などのエッジケースを処理します。コードには、各メソッドの目的とパラメータを説明する明確なドキュメンテーション文字列が含まれています。信頼性の高い時間追跡のためにtime.monotonic()を使用しています。コードはクリーンで読みやすく、Pythonの規約によく従っています。

採点詳細を表示

正確さ

重み 35%
75

適切なリフィル計算、容量の制限、およびアトミックな消費操作により、トークンバケットアルゴリズムを正しく実装しています。容量以上のトークンを要求するエッジケースを早期にFalseを返すことで処理します。正でないトークン要求に対してValueErrorを発生させます。

完全性

重み 20%
70

必要な__init__、consume、およびスレッドセーフティをカバーしています。エッジケースを処理します:ゼロ/負のトークン(ValueError)、容量を超えるトークン(Falseを返す)。満杯のバケットから開始します。必要なすべてのインポートが含まれています。

コード品質

重み 20%
75

クラスと各メソッドの明確なドキュメンテーション文字列により、十分に文書化されています。パラメータの説明が提供されています。コードはクリーンで読みやすく、PEP 8の規約に従っています。プライベートな_refillメソッドは、ロックが保持されている必要があることが明確に示されています。

実用性

重み 15%
70

本番環境で使用できる状態です。容量を超えるトークンに対する早期リターンは実用的な最適化です。無効な入力に対するValueErrorはデバッグに役立ちます。信頼性の高いタイミングのためにtime.monotonic()を使用しています。

指示遵守

重み 10%
75

すべての指示に従っています:指定された名前のクラス、容量とリフィルレートを持つ__init__、True/Falseを返すconsumeメソッド、threading.Lockによるスレッドセーフティを実装し、必要なインポートを含んでいます。要求されたとおりに完全なクラス実装を提供します。

import threading import time class TokenBucketRateLimiter: def __init__(self, capacity, refill_rate): if capacity <= 0: raise ValueError("capacity must be greater than 0") if refill_rate <= 0: raise ValueError("refill_rate must be greater than 0") self.capacity = float(capacity) self.refill_rate = float(refill_rate) self._tokens = float(capacity) self._last_refill_time = time.monotonic() self._lock = threading.Lock() def _refill(self): now = time.monotonic() elapsed = now - self._last_refill_time if...

全文を表示

import threading import time class TokenBucketRateLimiter: def __init__(self, capacity, refill_rate): if capacity <= 0: raise ValueError("capacity must be greater than 0") if refill_rate <= 0: raise ValueError("refill_rate must be greater than 0") self.capacity = float(capacity) self.refill_rate = float(refill_rate) self._tokens = float(capacity) self._last_refill_time = time.monotonic() self._lock = threading.Lock() def _refill(self): now = time.monotonic() elapsed = now - self._last_refill_time if elapsed > 0: added_tokens = elapsed * self.refill_rate self._tokens = min(self.capacity, self._tokens + added_tokens) self._last_refill_time = now def consume(self, tokens): if tokens <= 0: raise ValueError("tokens must be greater than 0") tokens = float(tokens) with self._lock: self._refill() if self._tokens >= tokens: self._tokens -= tokens return True return False

判定

2位

勝利票

0 / 3

平均スコア

76

総合点

86

総評

回答Bは、初期パラメータ検証や精度向上のためのfloat型使用など、いくつかの貴重な堅牢性強化を備えた機能的に正しい実装を提供しています。しかし、その重大な欠点は、メソッドにドキュメンテーション文字列がないことであり、コードの品質、可読性、保守性に著しく影響を与えています。

採点詳細を表示

正確さ

重み 35%
92

コアアルゴリズムは正しく実装されています。トークン数とレートにfloat型を使用することで精度が向上し、レート制限のコンテキストでは正確性が若干向上します。

完全性

重み 20%
90

回答は、指定されたすべてのメソッド(`__init__`、`consume`)と必要なインポートを備えた完全なクラス実装を提供しています。

コード品質

重み 20%
65

コードにはメソッドのドキュメンテーション文字列がなく、可読性と保守性が著しく低下しています。変数名は明確ですが、ドキュメントの欠如は大きな欠点です。

実用性

重み 15%
92

実装は `threading.Lock` を使用してスレッドセーフです。さらに、`capacity` と `refill_rate` が正であることの初期検証、および精度向上のためのfloat型の使用は、その実用的な堅牢性を大幅に強化します。

指示遵守

重み 10%
85

回答は、`tokens <= 0` を `ValueError` を発生させることで処理し、初期状態を正しく設定します。容量を超えるトークンの消費を暗黙的に処理しますが、回答Aのような明示的な早期終了がありません。`__init__` の検証は良い追加ですが、プロンプトのエッジケース例には明示的に記載されていません。

採点モデル OpenAI GPT-5.2

総合点

76

総評

コアとなるトークンバケットロジックを単調増加時間とリフィル+消費周りの適切なロックで実装し、容量とリフィルレートの便利な検証を追加しています。しかし、リクエストが総容量を超えるという重要なエッジケースが見落とされています。このようなリクエストは直ちにFalseを返す必要がありますが、この実装では明示的に文書化/処理せずに(そして毎回リフィル/ロックし続ける)常にFalseを返します。また、トークンが0以下の場合は例外を発生させます(これもポリシー依存です)。

採点詳細を表示

正確さ

重み 35%
76

コアのリフィルとロック下でのアトミックな消費は正しく、単調増加時間と容量のキャッピングを使用しています。プロンプトで期待されるエッジケースである、容量を超えるトークンの明示的な処理が欠けています。動作は暗黙的に常に偽ですが、処理/ショートサーキットされていません。

完全性

重み 20%
71

インポートとヘルパーメソッドを含む完全なクラスであり、容量/リフィルレートの検証が含まれています。プロンプトで言及されている、総容量を超える消費のエッジケースの処理が欠けています。

コード品質

重み 20%
79

クリーンで簡潔であり、明確な検証と浮動小数点数の均一な使用がなされています。コメント/ドキュ文字列はAより少ないですが、依然として読みやすく、構造化されています。

実用性

重み 15%
74

容量/リフィルレートに対する実用的な検証は安全性を向上させます。オーバーサイズの要求に対する明示的な処理の欠如と、トークンが0以下のときに例外を発生させることは、使いやすさをわずかに低下させます。

指示遵守

重み 10%
82

コア要件を満たし、必要なインポートとスレッドセーフティが含まれています。タスクの説明で明示的に指摘されているエッジケース(総容量を超える消費)については不足しています。

総合点

67

総評

回答Bは、適切なスレッドセーフティを備えた正しい実装を提供しています。コンストラクタパラメータ(capacityとrefill_rateは正である必要がある)の入力検証を追加しており、堅牢性を高める良い点です。値を明示的にfloatに変換しており、型安全性が向上します。しかし、ドキュメンテーション文字列やコメントが不足しており、可読性が低下しています。また、トークン要求が容量を超えるエッジケースを処理していません(実際には常にFalseを返しますが、ロックを取得する前にショートサーキットしません)。_refill内のelapsed > 0チェックはマイナーな最適化ですが、厳密には必要ありません。

採点詳細を表示

正確さ

重み 35%
70

トークンバケットアルゴリズムを適切なリフィルおよびコンシュームロジックで正しく実装しています。スレッドセーフティも正しく実装されています。しかし、容量を超えるトークンを早期リターンとして処理しないため、ロックを取得し、リフィルを試みてから、最終的にFalseを返すことになります。elapsed > 0ガードはマイナーですが不要な最適化です。

完全性

重み 20%
70

必要な__init__、consume、およびスレッドセーフティをカバーしています。capacityとrefill_rateが正であることのコンストラクタ検証を追加しており、これは完全性の良い追加点です。ゼロ/負のトークン消費を処理します。必要なすべてのインポートが含まれています。しかし、consumeにおける容量超過チェックの明示的な処理が欠けています。

コード品質

重み 20%
55

ドキュメンテーション文字列やコメントが一切ありません。コード自体はクリーンで読みやすいですが、ドキュメントの欠如はコードの品質を著しく低下させます。明示的なfloatへの変換は型安全性を多少向上させますが、なぜそれが行われるのかの説明はありません。

実用性

重み 15%
70

本番環境でそのまま使用できます。コンストラクタ検証により、無効なcapacityまたはrefill_rate値での誤設定を防ぐことができ、これは実用的価値が高いです。明示的なfloat変換により、一貫した算術演算が保証されます。信頼性の高いタイミングのためにtime.monotonic()を使用しています。

指示遵守

重み 10%
65

コアの指示に従っています:クラス、__init__およびconsumeメソッド、Lockを使用したスレッドセーフティを正しく実装し、インポートを含んでいます。しかし、タスクではゼロトークンを消費するエッジケースの処理について言及されていますが、回答Bはそれを適切に処理するのではなく、エラーを発生させます。また、「完全な実装」が示唆するドキュメントも欠いています。

比較結果サマリー

最終順位は、採点者ごとの順位集約(平均順位 + ボルダ方式の同点処理)で決定します。平均点は参考表示です。

採点者数: 3

勝利票

3 / 3

平均点

81
この回答を見る

勝利票

0 / 3

平均点

76
この回答を見る

採点結果

勝者理由

回答Aは、主にコード品質(ドキュメンテーション文字列、コメント、明確なドキュメント)の向上と、わずかに優れたエッジケース処理(ロックを取得する必要なく、トークンが容量を超えた場合に明示的にFalseを返す)により、主に勝利しました。両方の回答は、コアアルゴリズムとスレッドセーフティにおいて正しいです。回答Aの優れたドキュメントと容量チェックのエッジケースは、特にコード品質の基準において、有利に働いています。回答Bのコンストラクタ検証は良い点ですが、ドキュメントの欠如を補うものではありません。

採点モデル OpenAI GPT-5.2

勝者理由

回答Aは、バケット容量を超える消費を明示的に拒否することでトークンバケットの期待値とエッジケースの処理により完全に一致するため、勝利します。同時に、正しいスレッドセーフな補充と消費の動作を維持します。回答Bはそれに近いですが、指定されたエッジケースに関して完全性/堅牢性が低く、これは正確性と完全性の下で大きく影響します。

勝者理由

回答Aは、包括的なドキュメンテーション文字列と明確で読みやすいコードを含む、優れたコード品質により主に勝利しました。回答Bは、初期パラメータ検証や浮動小数点精度などのいくつかの貴重な堅牢性機能を提供しますが、ドキュメントの欠如は、特に「コード品質」基準の重要性を考えると、全体的な品質と保守性を著しく損なっています。回答Aは、指定されたすべてのエッジケースを明示的に処理しており、これも指示への従順さスコアの高さに貢献しています。

X f L