Накладные расходы и скорость кода (массив java.io.File против массива java.lang.String) - PullRequest
6 голосов
/ 10 мая 2011

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

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

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

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

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

Ответы [ 5 ]

14 голосов
/ 10 мая 2011

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

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

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

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

2 голосов
/ 10 мая 2011

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

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

2 голосов
/ 10 мая 2011

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

0 голосов
/ 10 мая 2011

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

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

Сказав это, массив объектов String превосходит массив объектов File с точки зрения памяти и скорости. И для этого есть несколько причин:

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

    • атрибут частного поля String

    • a transient поле длины префикса для специфичных для файловой системы префиксов

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

    • Как минимум, для создания объекта File требуется вызов 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

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

0 голосов
/ 10 мая 2011

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

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

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

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

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

...