开发者

Overhead vs. Speed of Code (java.io.File array vs. java.lang.String array)

just trying to sort out a small delimma I'm having here.

Currently, I'm working on an application that involves gathering a list of files into memory, to be deleted. Now, at this point, I thought that a java.io.File array would perhaps take up too much memory, since the list of Files in this context could be in the hundreds of possible entries.

Rather than eat excessive amounts of memory up with a list of File objects, I figured that gathering a list of filenames and storing them as a java.lang.String would be cheaper to memory. Now, here's my problem: With the goal in mind that these files are to be deleted, which of these would be cheaper:

  1. Storing an array of File objects rather than String objects, and calling .delete(); on each one in a loop (too much memory used).
  2. Storing an array of String objects with the filenames, but for each iteration of the loop, create a new File object using the list of filenames, and call .delete(); on that file (which means each time the loop iterates, a new File object is created and destroyed--possibly too much processor power being used).

I want to make the program as fast as possible, so either approach has its merits, and I just want to see which of these 开发者_如何学Gohas the least overhead. Thanks in advance!


The java.io.File represents the filename information/metadata about an entry in the filesystem, it does not contain the contents of the file.

In other words, code like new File("somelarge.txt") does not load the somelarge.txt file into memory.

The only real data that each File object contains is a String path to the File (along with a transient int prefixLength) - consider the File class merely a wrapper around the String path that knows how to invoke all of the filesystem operations.

The best choice here, barring some other requirements, is the code that is the easiest to read and conveys your intent the best.


I don't want to be rude, but let me start by invoking the "Avoid Premature Optimizations at all costs" mantra. Is your code performance sensitive? Do you have memory usage constraints? Neither hundreds of File objects or hundreds of File object creations in a loop sounds that bad. Still, if you really feel like optimizing, go with a Profiler and run some benchmarks using both strategies. I would personally recommend Netbeans Profiler.


A File is largely a wrapper for a String and consumes up to 32 bytes more than the String itself. If you have 1000 of these in a server where memory costs about $70/GB, the extra memory it consumes is worth about 0.22 cents. This is about the same as 1 second of your time if you are on minimum wage.

Unless you have a memory limited device, it is likely you don't need to worry about anything which consumes less than 1 MB.


Now, at this point, I thought that a java.io.File array would perhaps take up too much memory, since the list of Files in this context could be in the hundreds of possible entries.

Unless you are working with a seriously resource-starved system, you do not have the problem that you think you have.

Remember that a Java File object is only "an abstract representation of file and directory pathnames." As such, it represents a fixed memory cost for any file, no matter how large. If you are dealing with only hundreds of Files, you are almost certainly not approaching any sort of limit on heap space.

If you create a solution and find that you are facing memory limitations using profiling and monitoring, this implementation is one of the last places that you should look. It's simply not that much memory.

So, in short, you should write the code that you understand the best and will be able to maintain in the future. Simple code is your friend.


Sounds like premature optimization to me unless

  1. You are working with a resource-constrain mobile device, or
  2. The number of elements (file paths) in the array might be very large.

Having said that, an array of String objects beat an array of File objects in terms of memory and speed. And there are several reasons for this:

  1. A File object has a number of private attributes, including but not limited to

    • a private String field attribute

    • a transient prefix length field for filesystem-specific prefixes

  2. A File object instantiation relies on a static reference to an concrete implementation of java.io.FileSystem, to which the File constructor(s) make calls to it

    • At a minimum, construction of a File object requires a call to FileSystem.normalize() and FileSystem.prefixLength() (in addition to instantiating its own private references to the path and prefix length.

So, the cost of creating an array of n File instances equals

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

With an array of n String pathnames, the cost is just

 n * (avg_construction_of_individual_path_strings_off_filesystem)

In terms of space, the memory footprint of an array of n File objects will be:

 n * (avg_string_path_size + 32_bits_of_prefix_length + size_of_File_object_itself)

whereas an array of n String objects will be

 n * avg_string_path_size

For simplicity and convenience, I'd go with an array of Strings. I wouldn't even had bothered to do any estimation. Simpler tends to be better most of the time. And this minutia will only matter if you are working with a very constrained device (a mobile phone for instance.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜