Created
October 29, 2015 07:55
-
-
Save kokumura/3ac9d9da332a4ab40696 to your computer and use it in GitHub Desktop.
実行頻度リミッター
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
のようにすると、だいたい秒間100回くらいに調整される。("do something" 部分で平均0.01秒以上かかる場合は100回未満になるかもしれない。)