private static void runsorts(DataGenerator[] generators,
            SortRunner[] runners, DataSize[] sizes) {

        // Warm up the JVM so that the code (hopefully) gets compiled.
        System.out.println("Warming up the system, please wait...");
        String[] input = new String[DataSize.N_512000.getValue()];
        for (DataGenerator generator : generators) {
            String[] dataSet = generator.generate(DataSize.N_512000);
            for (SortRunner runner : runners) {
                System.arraycopy(dataSet, 0, input, 0, input.length);
                runner.sort(input);
            }
        }

        // For each type of data set, and each data set size, and
        // each sort implementation, run the sort several times and
        // calculate the average run time.
        for (DataGenerator generator : generators) {
            System.out.format("%s...\n", generator.getDisplayName());
            for (DataSize size : sizes) {
                System.out.format("\t%s...\n", size.toString());
                String[] dataSet = generator.generate(size);
                input = new String[size.getValue()];
                for (SortRunner runner : runners) {
                    System.out.format("\t\t%-20s:\t", runner.getDisplayName());
                    long[] times = new long[RUN_COUNT];
                    for (int run = 0; run < times.length; run++) {
                        System.arraycopy(dataSet, 0, input, 0, input.length);
                        long t1 = System.currentTimeMillis();
                        runner.sort(input);
                        long t2 = System.currentTimeMillis();
                        times[run] = t2 - t1;
                    }

                    // Find the average of the run times. The run times
                    // should never be more than a couple of minutes,
                    // so these calculations will never overflow.
                    long total = 0;
                    long highest = Long.MIN_VALUE;
                    long lowest = Long.MAX_VALUE;
                    for (int run = 0; run < RUN_COUNT; run++) {
                        total += times[run];
                        if (times[run] > highest) {
                            highest = times[run];
                        }
                        if (times[run] < lowest) {
                            lowest = times[run];
                        }
                    }
                    long average = total / RUN_COUNT;
                    System.out.format("%4d %4d %4d (low/avg/high) ms\n", lowest, average, highest);
                }
            }
        }
    }