开销与代码速度(java.io.File数组与java.lang.String数组)

开销与代码速度(java.io.File数组与java.lang.String数组),java,arrays,string,file,for-loop,Java,Arrays,String,File,For Loop,我只是想整理一下我在这里吃的一点美味佳肴 目前,我正在开发一个应用程序,该应用程序将文件列表收集到内存中,以便删除。现在,在这一点上,我认为java.io.File数组可能会占用太多内存,因为此上下文中的文件列表可能包含数百个可能的条目 我认为收集一个文件名列表并将其存储为java.lang.String比使用一个文件对象列表消耗过多的内存要便宜。现在,我的问题是:考虑到要删除这些文件的目标,以下哪种文件更便宜: 存储文件对象数组而不是字符串对象,并调用.delete();在循环中的每一个上(使

我只是想整理一下我在这里吃的一点美味佳肴

目前,我正在开发一个应用程序,该应用程序将文件列表收集到内存中,以便删除。现在,在这一点上,我认为java.io.File数组可能会占用太多内存,因为此上下文中的文件列表可能包含数百个可能的条目

我认为收集一个文件名列表并将其存储为java.lang.String比使用一个文件对象列表消耗过多的内存要便宜。现在,我的问题是:考虑到要删除这些文件的目标,以下哪种文件更便宜:

  • 存储文件对象数组而不是字符串对象,并调用.delete();在循环中的每一个上(使用了太多内存)
  • 使用文件名存储字符串对象数组,但对于循环的每次迭代,使用文件名列表创建一个新的文件对象,并调用.delete();在该文件上(这意味着每次循环迭代时,都会创建并销毁一个新的文件对象——可能使用了太多的处理器功能)

  • 我想使程序尽可能快,所以这两种方法都有其优点,我只想看看哪种方法的开销最小。提前谢谢

    java.io.File表示文件系统中某个条目的文件名信息/元数据,它不包含文件的内容

    换句话说,像
    newfile(“somelarge.txt”)
    这样的代码不会将
    somelarge.txt
    文件加载到内存中

    每个文件对象所包含的唯一真实数据是文件的“<代码>字符串路径< /代码>(连同<代码>瞬态INT PrimeLime< /COD>)-考虑<代码>文件<代码>类,只不过是一个围绕<代码>字符串路径< /C> >的包装器,它知道如何调用所有文件系统操作。< /P>


    除了一些其他要求外,这里最好的选择是最容易阅读的代码,并且最好地表达您的意图。

    我不想粗鲁无礼,但让我从调用“不惜一切代价避免过早优化”的口号开始。您的代码对性能敏感吗?你有内存使用限制吗?循环中的数百个
    文件
    对象或数百个
    文件
    对象创建听起来都没有那么糟糕。不过,如果您真的想优化,可以使用分析器,并使用这两种策略运行一些基准测试。我个人推荐

    现在,在这一点上,我认为 文件数组可能需要 由于 此上下文中的文件可能位于 数百个可能的条目

    除非您使用的是一个资源严重匮乏的系统,否则您不会遇到您认为存在的问题

    请记住,Java对象只是“文件和目录路径名的抽象表示”。因此,它表示任何文件的固定内存成本,不管文件有多大。如果您只处理数百个文件,那么几乎肯定不会接近堆空间的任何限制

    如果您创建了一个解决方案,并发现您在使用评测和监视时面临内存限制,那么此实现是您应该最后查看的地方之一。只是没有那么多的记忆


    因此,简而言之,您应该编写您最了解的代码,并在将来能够维护这些代码。简单的代码就是你的朋友。

    文件主要是字符串的包装器,比字符串本身多消耗32个字节。如果在一台内存成本约为70美元/GB的服务器上有1000个这样的内存,那么它所消耗的额外内存大约值0.22美分。如果你是最低工资,这大约相当于你的1秒时间


    除非您的设备内存有限,否则您可能不需要担心任何消耗小于1MB的设备。

    对我来说,这听起来像是过早的优化,除非

  • 您正在使用资源受限移动设备,或
  • 数组中的元素(文件路径)数量可能非常大
  • 话虽如此,字符串对象数组在内存和速度方面胜过文件对象数组。这有几个原因:

  • 文件对象具有许多私有属性,包括但不限于

    • 私有字符串字段属性

    • 文件系统特定前缀的
      临时
      前缀长度字段

  • 文件对象实例化依赖于对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
    

    为了简单和方便,我会使用一组字符串。我甚至不会费心做任何估算。大多数情况下,越简单越好。只有在使用非常受限的设备(例如手机)时,这些细节才会起作用

    你两种方法都试过了吗?哪一种更快?这在理论上是一个很难回答的问题。过早的优化是所有问题的根源。你是否确认
    文件
    数组占用了太多内存?Java的
    文件
    对象的大小当然超过了零,但它们只是对文件系统位置的引用。确实如此esn不能将文件的内容隐式地传输到您的程序中。@Kevin:适当强调