测量不同排序方法的时间

时间:2014-03-17 22:48:41

标签: java sorting user-interface

我正在编写代码,用于测量具有特定大小的数组的不同排序方法的不同排序时间,并在GUI中显示输出时间。我大部分时间都在工作,但程序每次都没有显示相同的结果。例如,一次运行将为0.2毫秒,下一次运行将为0.1毫秒。我相信问题出在runSort()方法中。有人能帮助我吗?这是代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
import java.util.Arrays;

public class Benchmarks extends JFrame
{
  private static int numberOfRuns = 20;

  private JTextField arraySizeInput, display;
  private String sortMethodNames[] =
  {"Selection Sort", "Insertion Sort", "Mergesort", "Quicksort", "Arrays.sort"};
  private JComboBox chooseSortMethod;

  private final long seed;
  private int arraySize;

// Constructor
   public Benchmarks()
  {

     super("Benchmarks");

     Container c = getContentPane();
     c.setLayout(new GridLayout(6, 1));

     c.add(new JLabel(" Array size: "));
     arraySizeInput = new JTextField(4);
     arraySizeInput.setText("1000");
     arraySizeInput.selectAll();
     c.add(arraySizeInput);

     chooseSortMethod = new JComboBox(sortMethodNames);
     c.add(chooseSortMethod);

     JButton run = new JButton("Run");
     run.addActionListener(new RunButtonListener());
     c.add(run);

     c.add(new JLabel(" Avg Time (milliseconds): "));

     display = new JTextField("   Ready");
     display.setBackground(Color.YELLOW);
     display.setEditable(false);
     c.add(display);

  // Use the same random number generator seed for all benchmarks
  //   in one run of this program:

     seed = System.currentTimeMillis();
  }

// Fills a[] with random numbers and sorts it using the sorting method
// specified in sortMethod:
//     1 -- Selection Sort
//     2 -- Insertion Sort
//     3 -- Mergesort
//     4 -- Quicksort
// This is repeated numberOfRuns times for better accuracy
// Returns the total time it took in milliseconds.
   private long runSort(double[] a, int sortMethod, int numberOfRuns)
  {
     long startTime;
     long endTime;
     long diffTime;  
     Random generator = new Random(seed);
     for(int i= a.length-1; i>0; i--)
     {
        a[i]= generator.nextDouble(); 
     }
     startTime= System.currentTimeMillis();

     switch(sortMethod) 
     {  
        case 1: //Selection Sort
           SelectionSort sel = new SelectionSort(); 
           sel.sort(a);
           break; 
        case 2: //Insertion Sort 
           InsertionSort nsert= new InsertionSort();
           nsert.sort(a); 
           break; 
        case 3: //Merge Sort 
           Mergesort merge = new Mergesort(); 
           merge.sort(a); 
           break; 
        case 4: // Quick Sort 
           Quicksort quick = new Quicksort();
           quick.sort(a); 
           break; 
     }
     endTime= System.currentTimeMillis();
     diffTime= endTime- startTime; 


     return  diffTime ;  
  }

// Handles Run button events
   private class RunButtonListener implements ActionListener
  {
      public void actionPerformed(ActionEvent e)
     {
        String inputStr = arraySizeInput.getText().trim();
        try
        {
           arraySize = Integer.parseInt(inputStr);
        }
            catch (NumberFormatException ex)
           {
              display.setText(" Invalid array size");
              arraySize = 0;
              return;
           }  

        if (arraySize <= 0)
        {
           display.setText(" Invalid array size");
           return;
        }

        if (arraySize <= 0)
           return;

        int sortMethod = chooseSortMethod.getSelectedIndex() + 1;
        double a[] = new double[arraySize];
        double avgTime = (double)runSort(a, sortMethod, numberOfRuns)
                                                      / numberOfRuns;
        display.setText(String.format("  %.2f", avgTime));

        arraySizeInput.selectAll();
        arraySizeInput.requestFocus();
        System.out.println("Array size = " + arraySize +
           " Runs = " + numberOfRuns + " " +
           sortMethodNames[sortMethod - 1] + " avg time: " + avgTime);

     }
  }

//************************************************************

   public static void main(String[] args)
  {
     numberOfRuns = 20;
     if (args.length > 0)
     {
        int n = -1;
        try
        {
           n = Integer.parseInt(args[0].trim());
        }
            catch (NumberFormatException ex)
           {
              System.out.println("Invalid command-line parameter");
              System.exit(1);
           }
        if (n > 0)
           numberOfRuns = n;
     }

     Benchmarks window = new Benchmarks();
     window.setBounds(300, 300, 180, 200);
     window.setDefaultCloseOperation(EXIT_ON_CLOSE);
     window.setVisible(true);
  }
}

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

由于许多次要因素,例如计算机当时的繁忙程度,您会得到不同的结果。此外,System.currentTimeMillis()本质上是不准确的;在某些系统上,5 ms可以测量为0到10 ms。为了在测量少量时间时获得更好的准确性,您应该使用System.nanoTime()。此外,在测量开始时间和测量结束时间之间,您应该什么都没有。这意味着 no for或while循环,if语句或switch语句。

答案 1 :(得分:0)

你尝试的是根本不可能的。您需要一个保证cpu时间的系统。但是调度和不同的负载使得无法获得准确的时间。另外,Java-Garbage集合以及从java环境中优化的内容会改变您的结果。你可以使用像junitbenchmark这样的框架让代码运行多次 - 但是这不会给你一个真正可用的#34;结果。它可以帮助您确定每个算法相对于彼此的速度。