тест и причина различия между C # и Java - PullRequest
5 голосов
/ 23 июня 2009

У меня загадочная ситуация, и мне нужно экспертное мнение относительно причины явления, объясненного ниже. Пару недель назад я провел сеанс под названием «Обзор .NET для Java-разработчиков», и в качестве его части я написал быстрый класс C # (3.5 framework) для чтения из файла и записи в другой файл построчно (в итерации). Поскольку моей аудиторией были Java-разработчики, у меня был один и тот же код в Java-классе для параллельного сравнения. Однако когда я запускал эти классы на одной и той же машине, к моему удивлению, Java-код последовательно выполнялся в два раза быстрее, чем C # -код. Я пробовал много оптимизаций в коде C #, чтобы сократить разрыв, но не смог добиться успеха. Должно быть объяснение, и я ищу человека, который мог бы объяснить причину. Я прилагаю исходный код из обоих классов для вашей справки.


класс Java

    public class ReadWriteTextFile {

    static public String getContents(File aFile, String OutPutFileName) {
    StringBuilder contents = new StringBuilder();

    try {
      BufferedReader input =  new BufferedReader(new FileReader(aFile));
      FileReader x = new FileReader(aFile);
      try {
        String line = null;
        while (( line = input.readLine()) != null){
              setContents(OutPutFileName, line + System.getProperty("line.separator"));
        }
      }
      finally {
        input.close();
      }
    }
    catch (IOException ex){
      ex.printStackTrace();
    }

    return contents.toString();
    }

  static public void setContents(String FileName, String aContents)
                                 throws FileNotFoundException, IOException { 
    try {
        FileWriter fstream = new FileWriter(FileName, true);
        BufferedWriter out = new BufferedWriter(fstream);
        out.write(aContents);
             out.close();
    } catch (Exception xe) {
        xe.printStackTrace();
    }
  }
  public static void main (String[] aArguments) throws IOException {

    System.out.println(getDateTime() + ": Started");
    File testFile = new File("C:\\temp\\blah.txt");
         String testFile2 = "C:\\temp\\blahblah.txt";

    for(int i=0; i<100; i++){
         getContents(testFile, testFile2);
     }

    System.out.println(getDateTime() + ": Ended");

  }

  private synchronized static String getDateTime() {
        DateFormat dateFormat = new SimpleDateFormat(
                                        "yyyy/MM/dd HH:mm:ss");
        Date date = new Date();
        return dateFormat.format(date);
    }
}

C # класс

class ReadWriteTextFile
{
    static void Main(string[] args)
    {
        System.Diagnostics.Trace.WriteLine(getDateTime() + ": Started");
        String testFile = "C:\\temp\\blah.txt";
        String testFile2 = "C:\\temp\\blahblah.txt";
        for(int i=0; i<100; i++){
            getContents(testFile, testFile2);
        }
        System.Diagnostics.Trace.WriteLine(getDateTime() + ": Ended");
    }

    static public void getContents(String sourceFile, String targetFile) {      
        try {
            using (StreamReader r = File.OpenText(sourceFile))
            {
                String line;
                while ((line = r.ReadLine()) != null)
                {
                    setContents(targetFile, line);
                }
                r.Close();
            }
    }
    catch (IOException ex){
        Console.WriteLine(ex.StackTrace);
    }
  }

  static public void setContents(String targetFile, String aContents)
  {

    try {
        //FileStream fsO = new FileStream(targetFile, FileMode.Append);
        //StreamWriter w = new StreamWriter(fsO);
        FileStream fs = new FileStream(targetFile, FileMode.Append,
                                FileAccess.Write, FileShare.None);
        using (StreamWriter w = new StreamWriter(fs))
        {
            w.WriteLine(aContents + "\n");
        }
    } catch (Exception xe) {
        Console.WriteLine(xe.StackTrace);
    }
  }

  private static String getDateTime() {
      DateTime dt = DateTime.Now;
      return dt.ToString("yyyy/MM/dd HH:mm:ss");
   }
}

Ответы [ 3 ]

8 голосов
/ 23 июня 2009

С одной стороны: в Java вы используете кодировку платформы по умолчанию. Это вполне может быть фиксированная кодировка «один байт на символ», которая, очевидно, будет проще, чем использование UTF-8, которое .NET делает по умолчанию.

Кроме того, вы пишете две строки в .NET и только одна в Java.

Одна вещь, которую нужно проверить, это то, привязаны ли вы к CPU или IO. Я бы ожидал , что это будет связано с вводом-выводом, но я, конечно, был удивлен до сих пор.

Наконец, вы должны запускать каждый тест после перезагрузки, чтобы попытаться максимально удалить дисковые кэши из уравнения.

3 голосов
/ 23 июня 2009

Я не вижу проблем с кодом здесь. Некоторые возможности: возможно, вы запускали код C # в режиме отладки? Возникла проблема с кэшированием файлов. Файл данных C # работал на сильно фрагментированной области диска. Я не ожидал бы, что такая простая программа на C # будет вдвое медленнее.

Редактировать: Я попробовал обе версии на 10439 байт blah.txt. Сгенерированный файл имел длину 1 043 900 байт.

C # (CTRL + F5) время было 18 секунд
C # (F5) время составило 22 секунды
Время Java было 17 секунд.

Оба приложения потребляли около 40% процессорного времени, половина этого времени была занята ядром.

Edit2: Ограничение ЦП связано с тем, что код постоянно открывает, закрывает и записывает небольшие порции данных. Это вызывает много переходов между управляемым и собственным ядром.

Моя системная спецификация: Core 2 Duo 2,4 ГГц, 2 ГБ 800 МГц RAM, WinXP SP3

2 голосов
/ 23 июня 2009

Медленная часть эталонных тестов выглядит так, как будто именно здесь один файл многократно открывается, оформляется, выполняется небольшая запись и снова закрывается. Не полезный тест. Очевидные различия заключаются в том, насколько велики буферы (с одной записью, на самом деле они вам не нужны) и синхронизируется ли полученный файл с диском.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...