// CSE 143, Winter 2009, Marty Stepp // This program compares the runtime of the sequential and binary // search algorithms. You can change the LENGTH and SEARCHES constants to // run it with a different amount of elements a different number of times. // // On Marty's computer, sequential search takes the following times: // 430 ms to perform 10000 searches over 10000 elements // 831 ms to perform 20000 searches over 10000 elements // 1542 ms to perform 40000 searches over 10000 elements // 3034 ms to perform 40000 searches over 20000 elements // 6069 ms to perform 40000 searches over 40000 elements // // (notice that it doubles if you double the number of searches, which would // be true for any searching algorithm; the runtime also doubles when we // double the size of the array, because sequential search is O(N), meaning // the rate of growth of the algorithm varies directly with the input size.) // // On Marty's computer, binary search takes the following times: // 561 ms to perform 1000000 searches over 1000000 elements // 1092 ms to perform 2000000 searches over 1000000 elements // 2203 ms to perform 4000000 searches over 1000000 elements // 2334 ms to perform 4000000 searches over 2000000 elements // 2504 ms to perform 4000000 searches over 4000000 elements // 2894 ms to perform 4000000 searches over 8000000 elements // // (notice that it doubles if you double the number of searches, which would // be true for any searching algorithm; but that the runtime hardly increases // at all when we double the size of the array, because binary search is // O(log N) compared to the input array size N.) // // If you want to run this program on your own computer, Java can run out of // memory when processing very large arrays of data. To give Java more // memory, you must add a special flag to the Java Virtual Machine. // In Eclipse, click Window, Preferences..., Java, Installed JREs, // then double-click whichever one you're using (probably jdk1.6.0), // then put the above under Default VM Arguments: // // -Xmx256m -Xms128m // // Those incantations give 256 megabytes to the Java heap (for storing objects) // and 128 MB to the call stack (for running methods) respectively. // Email Marty if you have any questions about this. import java.util.*; // for Random public class Searching { private static final Random RAND = new Random(); // global random generator private static final int LENGTH = 4000000; // length of array to search private static final int SEARCHES = 4000000; // number of searches to perform public static void main(String[] args) { System.out.println("Creating the array...\n"); int[] a = createArray(LENGTH); System.out.println("Performing searches...\n"); long startTime = System.currentTimeMillis(); // perform many searches and time how long it takes for (int i = 1; i <= SEARCHES; i++) { int index = binarySearch(a, 42); if (index >= 0 && a[index] != 42) { throw new RuntimeException("search returned an incorrect answer"); } } long endTime = System.currentTimeMillis(); long elapsedTime = endTime - startTime; System.out.println(elapsedTime + " ms to perform " + SEARCHES + " searches over " + LENGTH + " elements"); } public static int binarySearch(int[] a, int value) { return binarySearch(a, value, 0, a.length - 1); } private static int binarySearch(int[] a, int value, int min, int max) { // base case: no elements if (min > max) { return -1; } else { int mid = (min + max) / 2; if (a[mid] == value) { return mid; } else if (a[mid] < value) { // search the right portion of the array return binarySearch(a, value, mid + 1, max); } else { // a[mid] > value // search the left portion of the array return binarySearch(a, value, min, mid - 1); } } } // Returns the index of the given value in a, or -1 if not found. public static int sequentialSearch(int[] a, int value) { for (int i = 0; i < a.length; i++) { if (a[i] == value) { return i; } } return -1; } // Creates an array of the given length, fills it with random data, // arranges it into sorted order, and returns it. public static int[] createArray(int length) { int[] a = new int[length]; for (int i = 0; i < a.length; i++) { a[i] = RAND.nextInt(1000000000); } Arrays.sort(a); return a; } }