Java 从Linux文件系统读取文件的时间复杂度是多少?

Java 从Linux文件系统读取文件的时间复杂度是多少?,java,linux,filesystems,Java,Linux,Filesystems,假设我的文件系统中有大量目录(比如100.000),每个目录中都有相似数量的目录。每个目录可以包含任意数量的文件,但通常不超过几个。此结构具有恒定的深度(10) 我的问题是,如果我使用path.get()从以下目录结构读入文件,如:/dir-34/dir-215/dir-345/file1,与从这样的简单文件系统读入文件相比,时间复杂度(在读取操作中)是否有所不同: /dir1 /dir2 /dir3 file1 /dir4 file2 注意:这只是一个理论问题,我

假设我的文件系统中有大量目录(比如
100.000
),每个目录中都有相似数量的目录。每个目录可以包含任意数量的文件,但通常不超过几个。此结构具有恒定的深度(
10

我的问题是,如果我使用
path.get()
从以下目录结构读入文件,如:
/dir-34/dir-215/dir-345/file1
,与从这样的简单文件系统读入文件相比,时间复杂度(在读取操作中)是否有所不同:

/dir1
  /dir2
  /dir3
    file1
  /dir4
    file2

注意:这只是一个理论问题,我只是想知道我试图从中打开文件的目录/文件的数量是否会影响读取操作的速度。

一些流行的文件系统使用的数据结构比旧的文件系统更高效。ext4在默认情况下启用了目录散列(正如@ninjalj所指出的),XFS也是如此。这意味着在单个目录中的查找平均需要
O(1)
(如果您的路径具有固定的最大子目录数,则需要固定的时间)。这是根据

即使每个目录有无数个文件,访问单个文件的速度也非常快——但前提是您拥有完整的路径。如果您没有完整的路径,而必须在目录中查找模式,那么您将面临目录中条目数的
O(n)
。对于默认的系统级目录读取调用,较小的读取大小(32k)进一步加剧了这种情况


(虽然
ext4
目录可以有大量文件,但它们仅限于64000个子目录条目。)

如果
/path/to/file
可用,(注意:性能和时间复杂性仍将在很大程度上取决于磁盘结构和底层文件系统实现。例如btrfs,一切都是b树,ext4和XFS使用H树)

因此,对于遍历目录结构直到叶节点(包含文件的目录),平均情况时间复杂度应为O(logN),而最坏情况应为O(N),N=树中的目录数。最坏的情况是在N-1下创建第N个目录,在N-2中创建第N-1个目录,依此类推…直到根目录,形成树中的一个分支。理想情况下,如果有完整路径,则不必从根遍历树中的所有目录


然后,如果您的底层FS支持目录索引和散列,则每次查找都需要另一个O(1)来查找目录中的文件。因此,O(logN)+O(1),即忽略低阶项,它应该仅为O(logN),其中N是级别。

这里不清楚您在比较什么。在这两种情况下,听起来您都有一个嵌套的目录结构……还有,“时间复杂性”是指大O还是什么,或者您只是在说“运行时”?10万个目录,每个(!)包含100.000-这相当于10?googol?我比较了从嵌套目录结构(其中有
10*100.000
目录)加载文件的时间与只有10`的目录结构的加载时间。我感兴趣的是读取操作的时间复杂性,它取决于目录的数量。这取决于文件系统m及其选项。例如,Ext[234]有一个
dir\u index
选项,这意味着它将使用H树在目录中存储(文件名、索引节点)元组。给定恒定的目录深度10,复杂性为O(1),而不是O(logn)。这个问题的核心似乎是结尾处关于大目录性能的斜体部分。这种情况完全是基础目录索引的函数,而不是子目录树的结构。@DougLuce Hi,在计算时间复杂度时,最好采用平均和最坏情况,因此我考虑到N=树中没有目录,这是一个相当大的数目。对于任何树结构,查找总是O(logN)并且不能是O(1),假设我们有一个文件路径
/a/B/C/D/E/file
,要到达
E
下的目录,您必须至少进行四次查找()从根开始。问题中的问题在很大程度上是模糊的,取决于用于实现FS本身的数据结构。无论是在平均情况下还是在最坏情况下,级别数都不是O(logn)。正如问题中明确指出的那样,级别数是O(10)最大值。此外,对于任意数量的树结构,查找都不是O(logn)(链表、指数树等)。您好,道格,您可能指的是不同的数据结构,而在上述情况下,FS实现是其b树,而不是链表或指数表。[wiki]().
理想情况下,如果你有完整的路径,你不必从根目录遍历树中的所有目录。
不幸的是,拥有文件的路径并不能让你访问
/a/B/C/D/E/file的文件
你首先必须获得
a
的地址,然后必须获得
B
的地址等等。