番石榴RateLimiter经常运行

时间:2015-10-20 11:08:13

标签: java guava

我遇到了番石榴RateLimiter的问题。我使用RateLimiter.create(1.0)创建RateLimiter(“每秒1次允许”)并在每个周期调用rateLimiter.acquire(),但是当我测试运行时,我得到以下结果:

Average: 1232.0 Diff since last: 2540
Average: 1180.0 Diff since last: 258
Average: 1159.0 Diff since last: 746
Average: 1151.0 Diff since last: 997
Average: 1144.0 Diff since last: 1004

平均值是它平均睡眠的毫秒数,diff是自上次打印以来经过的毫秒数。平均而言没关系,它不允许我的代码每秒运行超过一次。但有时(正如你所看到的)它每秒运行不止一次。

你知道为什么吗?我错过了什么吗?

生成上述输出的代码:

private  int numberOfRequests;
private Date start;
private long last;
private boolean first = true;
private void sleep() {
    numberOfRequests++;
    if(first) {
        first = false;
        start = new Date();
    }

    rateLimiter.acquire();

    long current = new Date().getTime();
    double num = (current -start.getTime()) / numberOfRequests;
    System.out.println("Average: "+ num + " Diff since last: " + (current - last));
    last = current;
}

1 个答案:

答案 0 :(得分:0)

您的基准测试似乎存在缺陷 - 当我尝试复制它时,我发现非常接近每秒一次采集。这是我的基准:

public class RateLimiterDemo {
  public static void main(String[] args) {
    StatsAccumulator stats = new StatsAccumulator();
    RateLimiter rateLimiter = RateLimiter.create(1.0);
    rateLimiter.acquire(); // discard initial permit
    for (int i = 0; i < 10; i++) {
      long start = System.nanoTime();
      rateLimiter.acquire();
      stats.add((System.nanoTime() - start) / 1_000_000.0);
    }
    System.out.println(stats.snapshot());
  }
}

示例运行打印:

Stats{count=10, mean=998.9071456, populationStandardDeviation=3.25398397901304, min=989.303887, max=1000.971085}

差异几乎全部归因于基准开销(填充StatsAccumulator并计算时间增量)。

即使这个基准也存在缺陷(尽管我认为它不那么严重)。创建accurate benchmark 非常难,而简单的基准测试基准测试通常要么不准确,要么更糟糕,不能反映在生产环境中测试的代码的实际性能。 / p>