有一个需求,根据RPC耗时分段情况得到一个倍数系数,比如1到10ms的倍数是5,10ms到100ms的倍数3,100ms到1000ms的倍数是2.如果通过坐标图表示应该是一个沿x轴衰减的曲线,我首先想到通过对数来实现,我的一次实现方案:
for (int i = 1; i < 2000; ++i) {
double rate = (double) ((float) 3 / Math.log10(i < 2 ? 2 : i)) + 0.1;
if (rate < 1)
rate = 1;
float rate0 = Math.round(rate * 10) / 10.0f;
System.out.println(i + "\t" + rate0 + " \t " + Math.round(i * rate0));
}
由于log(10)10, log(10)100,log(10)1000的区间范围刚好是1--2---3。所以我的想法是用3除以对数,这样的结果:
i rate result
3 6.4 19
5 4.4 22
10 3.1 31
50 1.9 95
100 1.6 160
200 1.4 280
300 1.3 390
400 1.3 520
500 1.2 600
800 1.1 880
可以看到衰减得太快了。我这样思考这个问题,如果要让衰减变慢可以用减法:
数据范围:1------10------100------100------1000
rate范围:6.0----5.0----4.0-------3.0------2.0
第二次实现方案:
for (int i = 1; i < 2000; ++i) {
double rate = 6 - Math.log10(i);
float rate0 = Math.round(rate * 10) / 10.0f;
System.out.println(i + "\t" + rate0 + " \t " + Math.round(i * rate0));
}
i rate result
1 6.0 6
5 5.3 27
10 5.0 50
20 4.7 94
30 4.5 135
100 4.0 400
200 3.7 740
400 3.4 1360
500 3.3 1650
600 3.2 1920
800 3.1 2480
1000 3.0 3000
1900 2.7 5130