Skip to content

Instantly share code, notes, and snippets.

@kokumura
Created October 29, 2015 07:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kokumura/3ac9d9da332a4ab40696 to your computer and use it in GitHub Desktop.
Save kokumura/3ac9d9da332a4ab40696 to your computer and use it in GitHub Desktop.
実行頻度リミッター
public class Throttle {
protected final int maxHistorySize = 10;
protected final double timeEpsilon = 1d/(1000 * 1000);
protected double maxThrottlePerSec = 1d;
protected LinkedList<Double> history = new LinkedList<>();
public Throttle(double maxThrottle){
this.maxThrottlePerSec = maxThrottle;
}
public void waitLimit(){
synchronized(history){
double interval = planNextInterval();
if (interval >= timeEpsilon){
try {
long millis = (long)(interval*1000);
int nanos = (int)(interval*1000*1000*1000 - Math.floor(interval*1000)*1000*1000);
Thread.sleep(millis, nanos);
} catch (InterruptedException e) {
// do nothing
}
}
history.addLast(getCurrentTime());
while(history.size() > maxHistorySize)
history.removeFirst();
}
}
public double measureThroughput(){
synchronized(history){
if (history.size()<2) return 0d;
double sampleDuration = history.getLast() - history.getFirst();
int sampleSize = history.size()-1;
return sampleSize / sampleDuration;
}
}
protected static double getCurrentTime(){
return System.currentTimeMillis() * 0.001;
}
protected double planNextInterval(){
if (maxThrottlePerSec <= 0) return 0d;
double targetInterval = 1d/maxThrottlePerSec;
double currentTime = getCurrentTime();
if (!history.isEmpty()){
double lastTime = history.getLast();
return Math.max(targetInterval-(currentTime-lastTime), 0d);
} else {
return targetInterval;
}
}
public static void main(String[] args){
double maxThrottle = Double.parseDouble(args[0]);
Throttle thr = new Throttle(maxThrottle);
while(true){
thr.waitLimit();
System.out.println(thr.measureThroughput());
}
}
}
@kokumura
Copy link
Author

Throttle throttle = new Throttle(100);

while(true){

  // do something ...

  throttle.waitLimit();
}

のようにすると、だいたい秒間100回くらいに調整される。("do something" 部分で平均0.01秒以上かかる場合は100回未満になるかもしれない。)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment