Как StringBuilder можно использовать для чтения больших текстовых файлов в Java? - PullRequest
0 голосов
/ 24 марта 2012

Есть ли в Java какой-либо механизм для уменьшения использования памяти при чтении больших текстовых файлов?

Почти каждая программа, с которой я сталкивался, использует String для чтения текстовых файлов. Но Java резервирует место для каждого литерала String. Вот почему я думаю, что использование памяти увеличивается, поскольку все объекты String хранятся. Все классы java.io имеют дело со String. Но если мы не используем StringBuilder, то как мы можем уменьшить использование памяти?

Ведь сокращение использования памяти является главной задачей StringBuilder [так как он не является неизменным, как String]. Тогда как мы можем использовать эту функцию в операции ввода-вывода Java, не используя String, т.е. не используя что-то вроде этого: sb.append ([String object]);

Ответы [ 6 ]

1 голос
/ 24 марта 2012

Предположим, у вас есть n строки, каждая длиной 1, которые вы прочитали из своего ввода - для простоты.

Использование operator+ на стрингах во время чтения создаст объект String каждый раз, когда вы объединяете строки, поэтому вы получаете строки длиной 1,2,3, ..., n

Таким образом, общее использование памяти для объединенных строк составляет 1 + 2 + .. + n = O(n^2) в дополнение к n строкам, которые вы читаете из ввода

в то время как если вы используете StringBuilder для создания окончательной строки, вы фактически создаете n - для ввода [каждая длиной 1] и один объект для конечной строки - размером n, поэтому общее использование памяти 1 + 1 + .. + 1 + n = O(n)

Итак, даже если вы используете sb.append(String) - использование пространства асимптотически лучше, чем создание всех промежуточных строк - поскольку вам не нужно создавать промежуточные объекты String.

Кроме того - производительность [время] должна быть лучше при использовании StringBuilder - и потому, что вы создаете меньше объектов, и оба из-за меньшего использования памяти - gc не нужно работать так же усердно, как при наивной конкатенации строк .

(*) Обратите внимание, что легко заметить, что вышеупомянутое все еще верно для любой длины строк.

0 голосов
/ 24 марта 2012

Вместо String, попробуйте использовать StringBuilder, чтобы добавить данные, прочитанные из файла.Если вы используете String, вы можете создать несколько строковых объектов в памяти.

0 голосов
/ 24 марта 2012

Reader и его подклассы основаны на char и char [], только удобные методы используют String.Поскольку StringBuilder.append () принимает char [], вы можете избежать создания ненужных объектов String, если будете использовать только методы, построенные вокруг char [].

Обратите внимание, что при этом уменьшается количество временно создаваемых объектов String в общей памятитребования остаются прежними, gc будет собирать любые иные созданные строки.

0 голосов
/ 24 марта 2012

Возможно, вы захотите рассмотреть что-то вроде этого:

  BufferedReader reader = 
    new BufferedReader(
      new InputStreamReader(
        new ByteArrayInputStream(data)));
  String line;

  while ((line = reader.readLine()) != null)
    ...

Смотрите эти ссылки для более подробной информации:

BufferedReader для большого ByteBuffer?

http://www.tutorialspoint.com/java/java_bytearrayinputstream.htm

0 голосов
/ 24 марта 2012

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

0 голосов
/ 24 марта 2012

Вы можете использовать метод добавления строки StringBuilders, чтобы избежать создания промежуточных строк, посмотрите на этот пост: https://stackoverflow.com/a/9849624/102483 Имейте в виду, что нет способа уменьшить объем памяти конечной строки, чтобы это меньше, чем размер файла, который вы читаете.

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