【发布时间】:2013-04-14 20:03:29
【问题描述】:
我正在尝试根据我在下面的ConcurrentHashMap 中填充的数据集计算95th Percentile。
我很想知道在 95% 的时间内有多少电话回了电话
我的地图看起来像这样,它总是在键上按升序排序 - 其中
key - means number of milliseconds
value - means number of calls that took that much milliseconds
下面是我的地图数据-
Milliseconds Number
0 1702
1 15036
2 14262
3 13190
4 9137
5 5635
6 3742
7 2628
8 1899
9 1298
10 963
11 727
12 503
13 415
14 311
15 235
16 204
17 140
18 109
19 83
20 72
例如,从上面的数据集中,它的意思是
1702 个呼叫在 0 毫秒内返回
15036 个电话在 1 毫秒内返回
现在我可以通过将上述数据集插入Excel sheet 来计算第 95 个百分位数。但我正在考虑计算 Java 代码中的百分位数。
我知道算法看起来像这样-
对地图中的所有值求和,计算总和的 95%,迭代地图 以升序排列的键保持值的总和,以及何时 总和等于或超过先前计算的总和的 95%, 我猜关键应该是第 95 个百分位。
下面是包含上述数据集的地图。
Map<Long, Long> histogram = new ConcurrentHashMap<Long, Long>
我不确定我的算法是否也正确。我只是想知道在 95% 的时间内有多少电话回了。
以下是我目前基于上述算法得到的代码。
private static void logPercentileInfo() {
double total = 0;
for (Map.Entry<Long, Long> entry : CassandraTimer.histogram.entrySet()) {
long value = entry.getKey() * entry.getValue();
total += value;
}
double sum = 0.95*total;
double totalSum = 0;
for (Map.Entry<Long, Long> entry : CassandraTimer.histogram.entrySet()) {
totalSum += entry.getValue();
if(totalSum >= sum) {
System.out.println(entry.getKey());//this is the 95th percentile I guess
}
}
}
如果我从上述数据集中计算第 95 个百分位数时是否一切正确,请告诉我。如果也有任何改进,请告诉我。
更新代码:-
以下是我更新的代码,它解决了键的升序问题
/**
* A simple method to log 95th percentile information
*/
private static void logPercentileInfo() {
double total = 0;
for (Map.Entry<Long, Long> entry : CassandraTimer.histogram.entrySet()) {
long value = entry.getKey() * entry.getValue();
total += value;
}
double sum = 0.95*total;
double totalSum = 0;
SortedSet<Long> keys = new TreeSet<Long>(CassandraTimer.histogram.keySet());
for (long key : keys) {
totalSum += CassandraTimer.histogram.get(key);
if(totalSum >= sum) {
//this is the 95th percentile I guess
System.out.println(key);
}
}
}
谁能看一下,让我知道我是否正确计算了百分位数?
【问题讨论】:
-
由于您使用的是哈希映射,因此您的密钥不会按排序顺序存储。即,如果您在循环中打印出 entry.getKey(),您将看到键不按顺序排列。所以这是你的主要问题。 TeeMap 或 ConcurrentSkipListMap 将保持其键的顺序。
-
是的,你是对的。我忘了这样做。但请记住,我的地图已经按顺序排列了数据,那么逻辑是否正确?
-
你确定吗?打印你的钥匙我敢打赌你会发现它们不按顺序排列。
-
是的,我忘记了那部分。我的印象是,我按排序顺序存储它。让我更正一下,然后我会更新我的代码。
标签: java concurrenthashmap percentile