public static void main(String[] args) {
        Stats stats;
        if (args != null && args.length > 0 && "array".equalsIgnoreCase(args[0])) {
            stats = new ArrayStats(MAX_COUNT);
        } else {
            stats = new DirectBufferStats(MAX_COUNT);
        }
        final Message first = new Message(sequence.get(), "ROOT_MESSAGE");
        long currentSeq;
        long chunkStart = System.currentTimeMillis();

        while ((currentSeq = sequence.incrementAndGet()) < MAX_COUNT) {
            final long start = System.nanoTime();
            final Message next = nextMessage(first, currentSeq);
            cache.put(next.getSequenceId(), next);
            if (cache.size() > CACHE_CLEANUP_TRESHOLD && draw(CACHE_CLEANUP_PROBABILITY)) {
                for (int i = 0; i < CACHE_CLEANUP_CHUNK_SIZE; i++) {
                    cache.remove(cache.firstKey());
                }
            }
//  Allow for some OS-level thread preemption
//            LockSupport.parkNanos(1);
            stats.addObservation(System.nanoTime() - start);
            if (currentSeq % REPORTING_INTERVAL == 0) {
                System.out.println("Sequence: " + sequence);
                System.out.println("Messages/s: " + (REPORTING_INTERVAL * 1000 / (System.currentTimeMillis() - chunkStart)));
                chunkStart = System.currentTimeMillis();
            }
        }
        stats.printHistogram(6);
    }