Накладные расходы по сравнению Скорость кода (java.io .Массив файлов по сравнению с java.lang.Массив строк)

#java #arrays #string #file #for-loop

#java #массивы #строка #файл #for-цикл

Вопрос:

просто пытаюсь разобраться с небольшой проблемой, с которой я столкнулся здесь.

В настоящее время я работаю над приложением, которое включает в себя сбор списка файлов в памяти, подлежащих удалению. Теперь, на этом этапе, я подумал, что java.io .Файловый массив, возможно, занял бы слишком много памяти, поскольку список файлов в этом контексте может состоять из сотен возможных записей.

Вместо того, чтобы занимать чрезмерное количество памяти списком файловых объектов, я решил собрать список имен файлов и сохранить их как java.lang.Строка была бы дешевле для памяти. Теперь, вот моя проблема: имея в виду, что эти файлы должны быть удалены, какой из них будет дешевле:

  1. Сохранение массива файловых объектов, а не строковых объектов, и вызов .delete(); для каждого в цикле (используется слишком много памяти).
  2. Сохраняем массив строковых объектов с именами файлов, но для каждой итерации цикла создаем новый файловый объект, используя список имен файлов, и вызываем .удалить(); в этом файле (что означает, что каждый раз, когда цикл повторяется, создается и уничтожается новый файловый объект — возможно, используется слишком большая мощность процессора).

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

Комментарии:

1. Вы пробовали оба варианта? Что было быстрее? Теоретически ответить на этот вопрос довольно сложно.

2. преждевременная оптимизация — корень всего зла

3. Вы подтвердили, что File массив занимает слишком много памяти? File Объекты Java, конечно, имеют размер больше нуля, но это всего лишь ссылки на расположения файловой системы. Они неявно передают содержимое файлов в вашу программу.

4. @Kevin: С надлежащим акцентом на преждевременность ; на более слабых Droid это может быть действительно актуально (не уверен, что это действительно так , OP не разделил там достаточного контекста).

5. Использование File массива, если только сравнительный анализ после развертывания не показывает, что с этим подходом есть проблема. Спасибо.

Ответ №1:

java.io.File представляет информацию о имени файла / метаданные о записи в файловой системе, она не содержит содержимого файла.

Другими словами, подобный код new File("somelarge.txt") не загружает somelarge.txt файл в память.

Единственными реальными данными, которые содержит каждый файловый объект, являются String path данные для файла (вместе с transient int prefixLength ) — рассматривайте File класс просто как оболочку вокруг String path , которая знает, как вызывать все операции файловой системы.

Лучшим выбором здесь, за исключением некоторых других требований, является код, который легче всего читать и наилучшим образом передает ваши намерения.

Комментарии:

1. 1: A File содержит a String и an int , поэтому объем памяти не должен быть проблемой. Следите за удобочитаемостью.

Ответ №2:

Я не хочу быть грубым, но позвольте мне начать с обращения к мантре «Избегайте преждевременных оптимизаций любой ценой». Чувствительна ли производительность вашего кода? Есть ли у вас ограничения на использование памяти? Ни сотни File объектов, ни сотни File созданий объектов в цикле не звучат так плохо. Тем не менее, если вам действительно хочется оптимизировать, воспользуйтесь профилировщиком и запустите несколько тестов, используя обе стратегии. Я бы лично рекомендовал профилировщик Netbeans.

Ответ №3:

Файл в значительной степени является оболочкой для строки и потребляет на 32 байта больше, чем сама строка. Если у вас есть 1000 таких на сервере, где память стоит около 70 долларов за ГБ, дополнительная память, которую он потребляет, стоит около 0,22 цента. Это примерно то же самое, что 1 секунда вашего времени, если вы получаете минимальную заработную плату.

Если у вас нет устройства с ограниченной памятью, скорее всего, вам не нужно беспокоиться ни о чем, что потребляет менее 1 МБ.

Ответ №4:

Теперь, на этом этапе, я подумал, что java.io .Файловый массив, возможно, занял бы слишком много памяти, поскольку список файлов в этом контексте может состоять из сотен возможных записей.

Если вы не работаете с системой, испытывающей серьезную нехватку ресурсов, у вас нет проблемы, о которой вы думаете.

Помните, что объект Java File — это всего лишь «абстрактное представление путей к файлам и каталогам». Таким образом, это представляет собой фиксированную стоимость памяти для любого файла, независимо от его размера. Если вы имеете дело только с сотнями файлов, вы почти наверняка не приближаетесь к какому-либо ограничению пространства кучи.

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

Итак, короче говоря, вы должны написать код, который вы понимаете лучше всего и сможете поддерживать в будущем. Простой код — ваш друг.

Ответ №5:

Для меня звучит как преждевременная оптимизация, если только

  1. Вы работаете с мобильным устройством, ограничивающим ресурсы, или
  2. Количество элементов (путей к файлам) в массиве может быть очень большим.

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

  1. Файловый объект имеет ряд частных атрибутов, включая, но не ограничиваясь ими

    • атрибут поля private String

    • transient поле длины префикса для префиксов, зависящих от файловой системы

  2. Создание экземпляра файлового объекта основывается на статической ссылке на конкретную реализацию java.io.FileSystem, к которой обращаются конструкторы файлов

    • Как минимум, для создания файлового объекта требуется вызов FileSystem.normalize() и FileSystem.prefixLength() (в дополнение к созданию его собственных частных ссылок на путь и длину префикса.

Таким образом, стоимость создания массива из n экземпляров файлов равна

 n * (expense_of_constructor   avg_construction_of_individual_path_strings_off_filesystem)

expense_of_constructor = init_of_local_vars   expense_of_path_normalization   expense_of_prefix_length_computation
  

При использовании массива из n строковых путей затраты составляют всего

  n * (avg_construction_of_individual_path_strings_off_filesystem)
  

С точки зрения пространства, объем памяти массива из n файловых объектов будет равен:

  n * (avg_string_path_size   32_bits_of_prefix_length   size_of_File_object_itself)
  

в то время как массив из n строковых объектов будет

  n * avg_string_path_size
  

Для простоты и удобства я бы выбрал массив строк. Я бы даже не потрудился сделать какую-либо оценку. В большинстве случаев проще, как правило, лучше. И эта мелочь будет иметь значение, только если вы работаете с устройством с очень ограниченными возможностями (например, с мобильным телефоном).)

Комментарии:

1. Тем не менее, чтобы удалить файл, вам придется создавать File объект n раз.

2. Исправление: чтобы удалить a файл, вы создаете 1 файловый объект. Чтобы удалить n файлы, вы создаете n файловые объекты. Хотим ли мы создавать n файловых объектов одновременно или только по одному в момент удаления? Да, действительно, мы должны создать n количество файловых объектов, но есть большая разница между одновременным переносом их в массив и выполнением этого поэтапно, в зависимости от необходимости. В общем, вы создаете ресурс только в то время, когда это необходимо.

3.Да, это правда. Массив из n File объектов занимает больше памяти, чем массив из n String объектов.