@Setup public void setup() { data = new double[10000000]; for (int i = 0; i < data.length; i++) { data[i] = gen.nextDouble(); } fh = new FloatHistogram(0.1, 10000, binsPerDecade); for (int i = 0; i < 10000; ++i) { fh.add(gen.nextDouble()); } }
@Benchmark public void add(ThreadState state) { if (state.index >= data.length) { state.index = 0; } fh.add(data[state.index++]); }
@SuppressWarnings("WeakerAccess") public FloatHistogram(double min, double max, double binsPerDecade) { super(min, max); if (max <= 2 * min) { throw new IllegalArgumentException(String.format("Illegal/nonsensical min, max (%.2f, %.2g)", min, max)); } if (min <= 0 || max <= 0) { throw new IllegalArgumentException("Min and max must be positive"); } if (binsPerDecade < 5 || binsPerDecade > 10000) { throw new IllegalArgumentException( String.format("Unreasonable number of bins per decade %.2g. Expected value in range [5,10000]", binsPerDecade)); } // convert binsPerDecade into bins per octave, then figure out how many bits that takes bitsOfPrecision = (int) Math.ceil(Math.log(binsPerDecade * Math.log10(2)) / Math.log(2)); // we keep just the required amount of the mantissa shift = 52 - bitsOfPrecision; // The exponent in a floating point number is offset offset = 0x3ff << bitsOfPrecision; setupBins(min, max); }
@Override @SuppressWarnings("WeakerAccess") public void readObject(java.io.ObjectInputStream in) throws IOException { min = in.readDouble(); max = in.readDouble(); bitsOfPrecision = in.readByte(); shift = in.readByte(); offset = 0x3ff << bitsOfPrecision; int n = in.readShort(); ByteBuffer buf = ByteBuffer.allocate(n); in.readFully(buf.array(), 0, n); int binCount = bucketIndex(max) + 1; if (binCount > 10000) { throw new IllegalArgumentException( String.format("Excessive number of bins %d during deserialization = %.2g, %.2g", binCount, min, max)); } counts = new long[binCount]; Simple64.decompress(buf.asLongBuffer(), counts); }