Skip to content

得点の増え方を、公式コードから読もう

アプリが速くなればスコアは上がる。それは正しいのですが、もう少しだけ中身を知ると、次に守るべき場所が見えてきます。

今回は解説記事を使わず、公式ベンチマーカーのコードを読みました。ベンチマーカーは、採点するプログラムです。

スコアは、リクエスト数そのものではない

公式コードから、主な得点源は次の3つだと分かりました。

  • ISUの状態を送れた回数
  • 利用者が新しい状態を正しく読めた回数
  • graphを最後まで正しく読めた回数

さらに、ベンチ開始時は少人数ですが、サービスの反応がよいと5秒ごとに利用者が増えます。利用者が増えると、読む処理と登録が増え、得点の機会も広がります。

ゲームで言えば、速く答えると次の敵が追加され、その敵を倒すともっと得点できる仕組みです。終盤ほど負荷が重くなるのは、このためです。

graphは、一回の成功が大きい

公式コードの配点も読みました。graphは、返せた時刻の数によって4段階に分かれます。

得点源1回の点数
過去日のgraph・Good150
過去日のgraph・Normal100
過去日のgraph・Bad60
過去日のgraph・Worst10
今日のgraph・Good60
condition read・info20
condition read・warning8
condition read・critical4

最後の最高runではGraphGoodが13,578回でした。ここだけで約203万点です。condition POSTを速くするだけでなく、「送った履歴を、graphで漏れなく早く読める流れ」が大きな得点源でした。

timeoutは、1点引かれるだけではない

timeoutは「時間内に返事が来なかった」という意味です。公式ベンチは一定数のtimeoutを許しますが、利用者数に対して多くなりすぎると「サービスの評判が悪くなりました」と表示し、新しい利用者を増やさなくなります。

つまりtimeoutの影響は2つあります。

  1. 10件ごとに最終得点から引かれる
  2. 得点を生む新しい利用者が増えなくなる

後者のほうが痛い場面もあります。今回の外部ベンチでは、APIのp99は1〜2msでした。それでも、ごく少数の通信が100msを超えたため、runによっては利用者の増え方が鈍りました。

condition POSTの100ms

ISUが状態を送る処理は、約40msごとに動き、HTTP clientは100msでtimeoutします。ここから、平均だけ見て安心できない理由が分かります。

たとえば次の2つは、平均値だけならよく似ています。

  • すべてが5ms前後で返る
  • 99%は1msだが、1%が400ms止まる

後者はPOSTを落とし、timeoutを増やします。access logでは平均、p99、statusを一緒に見る必要があります。

人間が覚える4つの言葉

  • raw score: 減点前に積み上げた得点
  • deduction: 内容不一致やtimeoutなどによる減点
  • pass: 失格条件に当たらず、結果として採用できる状態
  • timeout: 制限時間内に応答できなかった回数

最高のraw scoreが出ても、deductionやHTTP 5xxを無視してはいけません。前の章で500を残した25,841点を不採用にしたのと同じです。

実際、仮登録を入れた最初の外部runは609,846点まで伸びましたが、POST /api/authの403が73件ありました。公式コードを見るとJWTの寿命は30秒です。mainの応答が詰まり、作られた認証requestが期限切れになるほど待たされた、と分かりました。点数は更新しても、このrunは採用しませんでした。

Agentに得点構造を調べてもらうプロンプト

text
公式ベンチマーカーのソースコードだけを読み、得点と負荷増加の仕組みを説明してください。

- 何をすると加点されるか
- timeoutとdeductionがどう扱われるか
- 利用者がいつ、何を条件に増えるか
- condition POSTの間隔とtimeout
- graph、condition read、condition postの得点内訳
- 最終scoreだけでなく途中経過から何を読めるか

定数名や関数名を根拠として示しつつ、初めて読む人にも分かる言葉へ置き換えてください。
解説記事は使わないでください。
公式ベンチマーカーのソースコードだけを読み、得点と負荷増加の仕組みを説明してください。

- 何をすると加点されるか
- timeoutとdeductionがどう扱われるか
- 利用者がいつ、何を条件に増えるか
- condition POSTの間隔とtimeout
- graph、condition read、condition postの得点内訳
- 最終scoreだけでなく途中経過から何を読めるか

定数名や関数名を根拠として示しつつ、初めて読む人にも分かる言葉へ置き換えてください。
解説記事は使わないでください。

この理解から変わった判断

1requestをさらに0.1ms縮めることだけでなく、100msを超える外れ値を消すこと、5秒ごとの利用者増加を止めないこと、150点のGood graphを増やすことを重視しました。

また、外部計測でPOST /api/conditionが90,009回、平均34.87ms、p99 2msという不思議な値になりました。99%までは速いのに、残り1%未満がとても長いため、平均だけが押し上げられています。この時点で、Goの中をさらに削るより、通信経路とHTTP接続を見る判断へ進めました。