11

これはかなり一般的な質問だと思いますが、グーグルで調べても答えが見つからないようです (私が知らない問題にはもっと正確な名前があるのではないでしょうか?)

ヒットを報告するために使用される「hit()」メソッドと hitsInLastSecond|Minute|Hour メソッドを使用して構造を実装する必要があります。ナノ秒の精度のタイマーがあります。これをどのように効率的に実装しますか?

私の考えは次のようなものでした(疑似C ++で)

class HitCounter {
  void hit() {
    hits_at[now()] = ++last_count;
  }

  int hitsInLastSecond() {
    auto before_count = hits_at.lower_bound(now() - 1 * second)
    if (before_count == hits_at.end()) { return last_count; }
    return last_count - before_count->second;
  }

  // etc for Minute, Hour

  map<time_point, int> hits_at;
  int last_count = 0;
};

これは機能しますか?いいですか?何か良いですか?

更新:プルーニングを追加し、コメントに従って両端キューに切り替えました:

class HitCounter {
  void hit() {
    hits.push_back(make_pair(now(), ++last_count));
  }

  int hitsInLastSecond() {
    auto before = lower_bound(hits.begin(), hits.end(), make_pair(now() - 1 * second, -1));
    if (before == hits.end()) { return last_count; }
    return last_count - before_count->second;
  }

  // etc for Minute, Hour

  void prune() {
    auto old = upper_bound(hits.begin(). hits.end(), make_pair(now - 1 * hour, -1));
    if (old != hits.end()) {
      hits.erase(hits.begin(), old)
    }
  }

  deqeue<pair<time_point, int>> hits;
  int last_count = 0;
};
4

1 に答える 1