// =================================================================================================
// Copyright 2013 Twitter, Inc.
// -------------------------------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this work except in compliance with the License.
// You may obtain a copy of the License in the LICENSE file, or at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =================================================================================================
package com.twitter.common.metrics.demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.twitter.common.objectsize.ObjectSizeCalculator;
import com.twitter.common.quantity.Amount;
import com.twitter.common.quantity.Data;
import com.twitter.common.stats.ApproximateHistogram;
import com.twitter.common.stats.Histogram;
import com.twitter.common.stats.testing.RealHistogram;
import static com.twitter.common.metrics.Histogram.DEFAULT_QUANTILES;
final class MetricsPrecisionDemo {
private MetricsPrecisionDemo() { }
private void testHistogram(Histogram h, RealHistogram real, List<Long> data) {
initializeWith(h, data);
initializeWith(real, data);
long histSize = ObjectSizeCalculator.getObjectSize(h);
long realSize = ObjectSizeCalculator.getObjectSize(real);
System.out.println("Real Histogram size: " + realSize + "B, Approx histogram size: "
+ histSize + "B");
double[] quantiles = DEFAULT_QUANTILES;
for (int i = 0; i < quantiles.length; i++) {
double q = quantiles[i];
long realQuantile = real.getQuantile(q);
long metricsQuantile = h.getQuantile(q);
double delta = 1000 * Math.abs(metricsQuantile - realQuantile) / realQuantile;
System.out.println("Quantile: " + q + "\tReal: " + realQuantile
+ " \tApprox: " + metricsQuantile
+ " (∂: " + (delta / 10.0) + "%)");
}
}
private Histogram initializeWith(Histogram h, List<Long> data) {
for (Long x: data) {
h.add(x);
}
return h;
}
private List<Long> getRandomData(int size, long min, long max) {
Random rnd = new Random(1);
List<Long> data = new ArrayList<Long>();
for (int i = 0; i < size; i++) {
data.add(min + (rnd.nextLong() % (max - min)));
}
return data;
}
private List<Long> getRealData(int n) {
List<Long> data = new ArrayList<Long>();
ClassLoader cl = getClass().getClassLoader();
InputStreamReader input =
new InputStreamReader(cl.getResourceAsStream("resources/real_latencies.data"));
BufferedReader reader = new BufferedReader(input);
try {
String line = reader.readLine();
int i = 0;
while (data.size() < n) {
if (line == null || "".equals(line)) {
data.add(data.get(i++));
} else {
long x = (long) (1000 * Double.parseDouble(line));
data.add(x);
line = reader.readLine();
}
}
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
public static void main(String[] args) {
MetricsPrecisionDemo demo = new MetricsPrecisionDemo();
for (int n = 100; n <= 1000 * 1000; n *= 10) {
for (long mem = 4; mem < 16; mem += 2) {
Amount<Long, Data> maxMemory = Amount.of(mem, Data.KB);
System.out.println("\nnumber of elements:" + n + " maxMemory:" + maxMemory);
System.out.println("Real data");
demo.testHistogram(new ApproximateHistogram(maxMemory), new RealHistogram(),
demo.getRealData(n));
System.out.println("Random data");
demo.testHistogram(new ApproximateHistogram(maxMemory), new RealHistogram(),
demo.getRandomData(n, 100000, 200000));
}
}
}
}