4

各スレッドがデータベースに挿入するのにかかる時間を測定しようとしています。ConcurrentHashMap各スレッドの挿入にかかる時間など、名前付きマップにこれらすべてのパフォーマンス数値をキャプチャしました。その同時ハッシュマップでは、次のようになります。

Key- 10
Value- 2

つまり、2回の通話が10ミリ秒で戻ってきました。以下の別の例

Key - 20
Value -1

つまり、1回の呼び出しが20ミリ秒で戻ってきました。

そして、そのマップにはより多くのデータが含まれるため、より多くのキーと値のペアが含まれます。

だから今、私は上記の同じマップを使用して以下のようなことをしようとしています。つまり、その特定の範囲で以下の数値を取得するには、上記のマップを繰り返す必要があります。それは可能ですか?

How many calls(X number) came back in between 1 and 20 ms
How many calls(X number) came back in between 20 and 40 ms
How many calls(X number) came back in between 40 and 60 ms
How many calls(X number) came back in between 60 and 80 ms
How many calls(X number) came back in between 80 and 100 ms
How many calls(X number) came back after 100 ms

私が最初に考えたいくつかのコード。

SortedSet<Long> keys = new TreeSet<Long>(map.keySet());
for (Long key : keys) {
    System.out.print(key + " : ");
    for (int i = 0; i < map.get(key); i++) {
                 // Not sure what I am supposed to do here?
    }
    System.out.println();
}

誰かがここで私を助けることができますか?

アップデート:-

私の地図のサンプル値-

{31=3, 48=1, 33=1, 30=12, 43=1, 38=1, 32=1}

これは、合計呼び出しがから3+1+1+12+1+1+1 = 20追加することによって行われたことを意味しますvaluemap

そして、その中から、上記のシナリオがこのようなものを意味することを理解する必要があります

How many calls(X number) came back in between 1 and 20 ms
How many calls(X number) came back in between 20 and 40 ms
How many calls(X number) came back in between 40 and 60 ms
How many calls(X number) came back in between 60 and 80 ms
How many calls(X number) came back in between 80 and 100 ms
How many calls(X number) came back after 100 ms

以下は私が以下の提案で試した私のコードです-

private static void drawHistogram(Map map){

int counter[] = new int[6];

for (Integer key : map.keySet()) {
    System.out.println("" + key);    

    // add sample
    int idx = key / 20;
    idx = Math.min(idx, counter.length - 1);
    counter[idx]++;
    }

for (int i = 0; i < counter.length; i++) {
    System.out.println(counter[i] + " came back in between " + i * 20 + " and " + (i + 1) * 20
            + " ms");
}

}

ご覧のとおり、20回の呼び出しがありますが、これは7回の呼び出しのみを示しています。私がしたことは何か間違っていますか?これは私が得た出力です-

0 came back in between 0 and 20 ms
5 came back in between 20 and 40 ms
2 came back in between 40 and 60 ms
0 came back in between 60 and 80 ms
0 came back in between 80 and 100 ms
0 came back in between 100 and 120 ms

これは7つの呼び出しのみを示しています。しかし、20の呼び出しがあります。

4

5 に答える 5

0

あなたは試すことができます:

SortedSet<Long> keys = new TreeSet<Long>(map.keySet());

int group1To20=0;
int group20To40=0;
int group40To60=0;
int group60To80=0;
int group80To100=0;
int groupAbove100=0;
for (Long key : keys) {
 if(key>=0 && key<=20){
  group1To20=group1To20+map.get(key);
  }elseif(key>20 && key<=40){
   group20To40=group20To40+map.get(key);
  }
 //Similarly do as above for other range of group

}//end of loop


System.out.print("group 1-20 contains " +  group1To20);
//Now print the group range and values here

}

私はあなたの解決策を試しました。私はあなたの質問を誤解するかもしれません。もしそうなら、私のために質問を明確にしてください。

于 2013-02-08T06:23:36.760 に答える
0

地図はまったく必要ありません。単純に時間を 20 (ミリ秒) で割り、配列内のカウンターをインクリメントすることができます。

public static void main( String[] args) {
    int counter[] = new int[6];
    for ( int i = 0 ; i < 100 ; i++ ) {
        int time = (int) ( Math.random() * 200 );
        System.out.println( "" + time  );
        // add sample
        int idx = time / 20;
        idx = Math.min( idx, counter.length-1);
        counter[idx]++;
    }

    for ( int i = 0 ; i < counter.length ; i++ ) {
        System.out.println( counter[i] + " came back in between " + i*20 + " and " + (i+1)*20 + " ms" );
    }
}

最後の配列要素はすべてのサンプル数を保持することに注意してください >= 100ms であるため、出力を修正する必要があります。コードをできるだけ短く明確にするために省略されています。

出力例

13 came back in between 0 and 20 ms
10 came back in between 20 and 40 ms
13 came back in between 40 and 60 ms
10 came back in between 60 and 80 ms
11 came back in between 80 and 100 ms
43 came back in between 100 and 120 ms

更新:本来あるべき出力

for ( int i = 0 ; i < counter.length-1 ; i++ ) {
    System.out.println( counter[i] + " came back in between " + i*20 + " and " + (i+1)*20 + " ms" );
}
System.out.println( counter[counter.length-1] + " came back after 100" ms" );
于 2013-02-08T06:22:14.513 に答える
0
SortedSet<Long> keys = new TreeSet<Long>(map.keySet());
Map<Long, Long> values = new HashMap<Long, Long>();
Integer total = null;
Integer current = null;
Long point = null;
for (Long key : keys) {
    System.out.print(key + " : ");
    current = map.get(key);
    if(key >= 1 && key <= 20) {
        point = 1;
    } // Do Other Comparisons also and change point 2, 3, 4, 5, 6

    total = values.get(point);
    if(total == null) {
        total = 0;
    }
    total += current;
    values.put(point, total);
    System.out.println();
}

keySetループすると of がスローされますvalues

ポイント1になりますHow many calls(X number) came back in between 1 and 20 ms

于 2013-02-08T06:08:18.747 に答える
0

NavigableMap数値の範囲 (先頭、末尾) を照会できる を使用できます。スレッドセーフな実装はConcurrentSkipListMap.

特に、メソッドを見てNavigableMap<K,V> headMap(K toKey, boolean inclusive)くださいNavigableMap<K,V> tailMap(K fromKey, boolean inclusive)SortedMap<K,V> subMap(K fromKey, K toKey)

//your existing concurrent map changed to concurrent navigable map
NavigableMap<Long, Long> throughputCounter = new ConcurrentSkipListMap<Long, Long>();
            // this prints for inclusive values - 1 and 20 are both included
            System.out.println("How many calls(X number) came back in between 1 and 20 ms:" + calcThroughput(throughputCounter.subMap(1L, true, 20L, true)));
            System.out.println("How many calls(X number) came back in between 20 and 40 ms:" + calcThroughput(throughputCounter.subMap(20L, true, 40L, true)));
            System.out.println("How many calls(X number) came back in between 40 and 60 ms:" + calcThroughput(throughputCounter.subMap(40L, true, 60L, true)));
            System.out.println("How many calls(X number) came back in between 60 and 80 ms:" + calcThroughput(throughputCounter.subMap(60L, true, 80L, true)));
            System.out.println("How many calls(X number) came back in between 80 and 100 ms:" + calcThroughput(throughputCounter.subMap(80L, true, 100L, true)));
            System.out.println("How many calls(X number) came back in after 100 ms:" + calcThroughput(throughputCounter.tailMap(100L)));

    private Long calcThroughput(NavigableMap<Long, Long> subMap) {
        Long sumOfARange = new Long(0);
        for (Long value : subMap.values()) {
            sumOfARange += value;
        }
        return sumOfARange;
    }
于 2013-02-08T06:09:44.150 に答える
0

バケット サイズ (および実際に集約するバケットの数) を簡単に再定義する必要性を予測して、私は次のことを提案します。

    Map<Integer, Integer> values = new HashMap<Integer, Integer>();

    int[] definition = {0, 20, 40, 60, 80, 100};
    int[] buckets = new int[definition.length];

    for (int time : values.keySet()) {
        for (int i=definition.length-1; i>=0; i--) {
            if (time >= definition[i]) {
                buckets[i] += values.get(time);
                break;
            }
        }
    }
    for (int i=0; i<definition.length; i++) {
        String period = "";
        if (i == definition.length-1) {
            period = "greater than " + definition[i] + "ms";
        } else {
            period = "between " +
                      (definition[i]+1) +
                      " and " +
                      definition[i+1] + "ms";
        }
        System.out.println(buckets[i] + " came back " + period);
    }

構成可能性は、変更によって管理されdefinitionます。これをテストするために次のコードを使用しました。

    Random rnd = new Random();
    for (int i=0; i<1000; i++) {
        int time = rnd.nextInt(121);
        Integer calls = values.get(time);
        if (calls == null) {
            calls = Integer.valueOf(0);
        }
        calls += 1;
        values.put(time, calls);
    }
于 2013-02-08T06:52:00.753 に答える