Java эффективная запись файлов: конкатенация строк или дополнительный вызов write () - PullRequest
1 голос
/ 02 февраля 2012

В приведенном ниже коде, какой случай (1 или 2) является более "эффективным"?

static final String NEWLINE = System.getProperty("line.separator");
Vector<String> text_vec = ...;
FileWriter file_writer = new FileWriter(path);
BufferedWriter buffered_writer = new BufferedWriter(file_writer);
try {
    for (String text: text_vec) {

        // Case 1: String concatenation
        buffered_writer.write(text + NEWLINE);

        // Case 2: Extra call to write()
        buffered_writer.write(text);
        buffered_writer.write(NEWLINE);
    }
}
finally {
    buffered_writer.close();
}

В случае # 1, как я понимаю, конкатенация строк обрабатывается компилятором Java автоматическивыделение объекта StringBuilder.Поскольку значения String неизвестны во время компиляции, объединить «рано» (во время компиляции) невозможно.

Таким образом, возникает вопрос: какой из них более эффективен (процессор / память / время настенных часов))?

Я оставляю точное определение «эффективного» тем, кто отвечает.Я не эксперт по виртуальной машине Java.

Ответы [ 4 ]

3 голосов
/ 02 февраля 2012

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

Кроме того, не забудьте очистить буфер, когда закончите запись в него.

1 голос
/ 22 октября 2012

Второй должен быть быстрее, так как предотвращает создание бесполезного объекта String, потому что запись BufferedWriter напрямую преобразует свой ввод в байты / символы вместо создания бесполезных строковых объектов.

В случае 1:

Ваш код составляет:

1 time StringBuilder; (подразумевается добавлением строк вместе)

1 time String; (подразумевается добавлением строк вместе)

1 time char[]; Автором в буфере

С делом 2:

Ваш код составляет:

2 time char[]; Автором в буфере


Поскольку в последнем случае меньше объектов и меньше объектов, это должно быть быстрее.

0 голосов
/ 02 февраля 2012

Все проходит через буфер, поэтому разницы должно быть мало.Возможно, версия 2 с дополнительной записью работает быстрее.

Но если вы не сделаете это миллион раз, это не будет иметь значения.

0 голосов
/ 02 февраля 2012

File IO на несколько порядков медленнее, чем все, что вы делаете с конкатенацией строк в JVM. Диск будет вашим узким местом, несмотря ни на что.

Это предполагает, что мы не говорим о SSD, который, вероятно, все еще медленнее, чем сама JVM.

РЕДАКТИРОВАТЬ: Очевидно, что не очень хорошо общаться на основе комментариев. Попробуй в большем текстовом поле. ОП указал FileWriter. Это означает, что в конечном итоге все данные должны идти на диск. Задержка диска измеряется в миллисекундах, а пропускная способность - в мегабайтах / секунду, обычно 10 с, но не 100 с.

Задержка памяти измеряется в наносекундах, а пропускная способность - в гигабайтах в секунду. Большая часть вашей конкатенации строк происходит там. Это на 3-6 порядков быстрее, чем у диска.

Независимо от того, как вы буферизуете, объединяете и т. Д., В конечном итоге вы столкнетесь с ограничениями пропускной способности диска. Особенно, если вы запустите flush () и подождите, пока он действительно завершит процесс сброса на носитель.

Буферизация не означает приседания, кроме повышения эффективности дискового ввода-вывода. Да, вы должны использовать буфер при записи, что-то порядка 1k-16k достаточно. Однако этот буфер НЕ изменит пропускную способность вашего диска. Это на несколько порядков медленнее, чем проблема конкатенации строк.

Итак. Если вы хотите говорить об эффективности при записи на диск, забудьте о том, как вы объединяете строки. Просто упростите чтение кода.

...