2017-01-01 9 views
2

ミリ秒単位の長いレイテンシの配列が与えられているので、それらからパーセンタイルを計算したいと思います。私は仕事をする方法の下にあるが、私はこれが私に正確な結果を与えるかどうかをどのように確認できるか分からない。長い配列からパーセンタイルを計算しますか?

public static long[] percentiles(long[] latencies, double... percentiles) { 
    Arrays.sort(latencies, 0, latencies.length); 
    long[] values = new long[percentiles.length]; 
    for (int i = 0; i < percentiles.length; i++) { 
     int index = (int) (percentiles[i] * latencies.length); 
     values[i] = latencies[index]; 
    } 
    return values; 
    } 

私はlatencies配列から第50、第95、第99および99.9thパーセンタイルを取得したいと思います。

long[] percs = percentiles(latencies, 0.5, 0.95, 0.99, 0.999); 

この方法は、長い待ち時間のためにパーセンタイルを得る正しい方法ですか?私はJava 7で作業しています。

+0

だけでなく、あなたの 'percentiles'方法は、パーセンタイル値(必ずしも正しく計算しないことに注意してください - 私の答えを参照)とリターンを値に加えて、 'latencies'配列がソートされたままになります。これは、望ましくないかもしれない副作用です。これはおそらくあなたが書こうとしている小さなプログラムでは無害ですが、一般的にメソッドの目的ではない副作用がメソッドにあるとは好ましくありません。 – ajb

答えて

1

Wikipediaによれば、パーセンタイルの標準定義はありません。しかし、それらはいくつかの可能な定義を与える。あなたが投稿したコードは、最近のランク方法に最も近いように見えますが、それは全く同じではありません。

それらが与える式Nは、リストの長さである

n = ceiling((P/100) x N) 

は、Pはパーセンタイルであり、そしてn序ランクであろう。あなたはすでに100で除算を行っています。彼らが与える例を見ると、 "順序ランク"はリストのインデックスですが、それは1相対です。このように、Java配列へのインデックスを取得するには、したがって、正しい式はあなたのコード内の変数を使用して

n = ceiling(percentile * N) - 1 

する必要があり、Javaの当量が

(int) Math.ceil(percentiles[i] * latencies.length) - 1 
だろう1を減算する必要があると思います

これはあなたが書いたコードではありません。 doubleintにキャストすると、結果は0に丸められます。つまり、 "floor"関数と同じです。 percentiles[i] * latencies.lengthが整数でない場合ので、あなたのコードが

floor(percentiles[i] * latencies.length) 

を計算し、結果は同じいずれかの方法です。しかし、 "floor"と "ceiling"が同じ値になるように整数の場合、結果は異なります。

ウィキペディアの例は、リストが{15,20,35,40,50}のときの40パーセンタイルを計算することです。彼らの答えは、0.40 * 5 = 2.0、天井(2.0)= 2.0なので、リストの2番目のアイテム、つまり20を見つけることです。

しかし、あなたのコード:

int index = (int) (percentiles[i] * latencies.length); 

はそれがあなたのリストの3番目のアイテムを与えるので、代わりに第二の、あなたが望むものではありませんこれは、2であることindexになります。

したがって、ウィキペディアの定義と一致させるには、インデックスの計算を少し修正する必要があります。 (一方で、誰かが来て、あなたの計算が正しいと言って、ウィキペディアが間違っていると言っても、私は驚かないでしょう。)

1

これは、あなたが探しているものです。

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<long> latencies = new List<long>() { 3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20 }; 

     Console.WriteLine(Percentile(latencies,25)); 
     Console.WriteLine(Percentile(latencies, 50)); 
     Console.WriteLine(Percentile(latencies, 75)); 
     Console.WriteLine(Percentile(latencies, 100)); 

     Console.ReadLine(); 
    } 

    public static long Percentile(List<long> latencies, double Percentile) 
    { 
     latencies.Sort(); 
     int Index = (int)Math.Ceiling(((double)Percentile/(double)100) * (double)latencies.Count); 
     return latencies[Index-1]; 
    } 
} 

enter image description here

+2

えええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええご> – ajb

関連する問題