user2348367
user2348367

Reputation:

How can I measure the times of my sorting algorithms in a single step?

I am working on a exercise but I am stuck on one point

I want to measure the sorting times of 3 sorting algorithms (bubble,insertion and selection) using seven different arrays. I have tried multiple ways but I can't measure the sorting time of all three algorithms in a single step for all the arrays. My programme should:

The results are always coming 0 millisecond but it can not be like that because I tried 1million integer array so, there is no possibility for coming 0 millisecond for it.Finally, I tried "for loop " for achieving the what will I do.

I should write the all my methods because you may find another errors in other methods.

public static void randomlyFillArray(int[] array, int a, int b) {
    for (int i = 0; i < array.length; i++) {
        array[i] = randomInt(a, b);
    }
}

public static int randomInt(int a, int b) {
    return (int) ((b - a + 1) * Math.random() + a);

}

public static void SelectionSort(int[] array) {

    for (int i = 0; i < array.length - 1; i++) {
        for (int j = i + 1; j < array.length; j++) {
            if (array[i] > array[j]) {
                // ... Exchange elements
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

public static void insertionSort(int[] array) {
    int i, j, temp;
    for (i = 1; i < array.length; i++) {
        temp = array[i];
        j = i;
        while (j > 0 && array[j - 1] > temp) {
            array[j] = array[j - 1];
            j--;
        }
        array[j] = temp;
    }
}

public static void bubbleSort(int[] array) {
    boolean swapped = true;
    int j = 0;
    int temp;
    while (swapped) {
        swapped = false;
        j++;
        for (int i = 0; i < array.length - j; i++) {
            if (array[i] > array[i + 1]) {
                temp = array[i];
                array[i] = array[i + 1];
                array[i + 1] = temp;
                swapped = true;
            }
        }
    }
}

public static void main(String[] args) {
    // int[] array500 = new int[500];  //These are my arrays that I should do the process for //each one.
    // int[] array1000 = new int[1000];
    // int[] array5000 = new int[5000];
    // int[] array10000 = new int[10000];
    // int[] array50000 = new int[50000];
    // int[] array100000 = new int[100000];
    // int[] array500000 = new int[500000];
    // int[] array1000000 = new int[1000000];
    for (int i = 0; i < 4; i++) {

        int[] array = new int[500];
        if (i == 1) {
            randomlyFillArray(array, 1, 1000);
            SelectionSort(array);

            long startTime = System.currentTimeMillis();
            long total = 0;

            long stopTime = System.currentTimeMillis();
            long elapsedTime = stopTime - startTime;
            SelectionSort(array);
            System.out.println("SelectionSort for 500 integer :  "
                    + elapsedTime);

        } else if (i == 2) {
            randomlyFillArray(array, 1, 1000);
            insertionSort(array);
            long startTime = System.currentTimeMillis();

            long total = 0;

            long stopTime = System.currentTimeMillis();
            long elapsedTime = stopTime - startTime;
            insertionSort(array);
            System.out.println("InsertionSort for 500 integer :  "
                    + elapsedTime);
        } else if (i == 3) {
            randomlyFillArray(array, 1, 1000);
            bubbleSort(array);

            long startTime = System.currentTimeMillis();
            long total = 0;

            long stopTime = System.currentTimeMillis();
            long elapsedTime = stopTime - startTime;
            bubbleSort(array);

            System.out.println("BubbleSort for 500 integer :  "
                    + elapsedTime);

        }

    }

}

Thank you for your all advices stackoverflow family.

Sincerely.

Upvotes: 4

Views: 8691

Answers (2)

Max Fichtelmann
Max Fichtelmann

Reputation: 3504

creating microbenchmarks can be tricky, because the JIT compiles frequently used code, which takes some time of its own...

so my approach is usually like this:

public void measureSorting(int[] array) {
    // this should be sufficiently large
    long start, end;
    randomlyFillArray(array, 1, 1000);

    // warm up JIT - execute without measuring
    SelectionSort(array);
    randomlyFillArray(array, 1, 1000);

    // stop the time
    start = System.currentTimeMillis();
    SelectionSort(array);
    end = System.currentTimeMillis();

    System.out.printf("SelectionSort for %d integer :  %d milliseconds", array.length, end-start);

    // repeat for other algorithms
}

If you are using Java8, you can even create something like this:

public static void measureSorting(int[] array, Consumer<int[]> sortingFunction) {
    // this should be sufficiently large
    long start, end;
    randomlyFillArray(array, 1, 1000);

    // warm up JIT - execute without measuring
    sortingFunction.accept(array);
    randomlyFillArray(array, 1, 1000);

    // stop the time
    start = System.currentTimeMillis();
    sortingFunction.accept(array);
    end = System.currentTimeMillis();

    // repeat for other algorithms

    System.out.printf("%s for %d integer :  %d milliseconds", sortingFunction, array.length, end-start);
}

public static void main(String[] args) {
    // assuming the enclosing class is Sorter
    measureSorting(new int[500], Sorter::SelectionSort);
    measureSorting(new int[500], Sorter::insertionSort);
    measureSorting(new int[500], Sorter::bubbleSort);
}

Upvotes: 2

tobias_k
tobias_k

Reputation: 82899

All your timing blocks look like this:

randomlyFillArray(array, 1, 1000);
SelectionSort(array);
long startTime = System.currentTimeMillis();
long total = 0;
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
SelectionSort(array);
System.out.println("SelectionSort for 500 integer :  " + elapsedTime);

You sort, then take the start time, then immediately take the end time, then sort again, then print the times. You have to take the end time after the sort. If you have a reason for sorting twice ('warming up' the JVM?), make sure that you re-randomize the array before you do the timed sort. An algorithm's performance for sorting an already sorted array might be much different.

randomlyFillArray(array, 1, 1000);
long startTime = System.currentTimeMillis();
long total = 0;  // this thing is never used...
SelectionSort(array); // move this line between start time and end time!
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("SelectionSort for 500 integer :  " + elapsedTime);

Also, much of that code is the same for each of those sorts. You can move those parts out of the if/else blocks and into the loop, making the whole code more compact and easier to maintain. Also, you can create another loop around that one for the different array sizes.

for (int num : new int[] {500, 1000, 5000, ...}) {
    for (int i = 0; i < 4; i++) {
        String sort = null;
        int[] array = new int[num];
        randomlyFillArray(array, 1, 1000);
        long startTime = System.currentTimeMillis();
        if (i == 1) {
            sort = "SelectionSort";
            SelectionSort(array);
        } else if (i == ...) {
            // analogeous for other sorts
        }
        long stopTime = System.currentTimeMillis();
        long elapsedTime = stopTime - startTime;
        System.out.println(sort + " for " + num + " integers: " + elapsedTime);
    }
}

Upvotes: 5

Related Questions