2017-02-15 29 views
2

我有一个代码迭代超过100 000个文件,并获得他们的相对路径到一些根目录和代码工作,但比其他丑陋的解决方案(它是奇怪的代码,但它的速度更快)相对较慢。java文件相对方法性能

原始代码是在这里:

File file, URI rootDirURI 
for() { 
    blabla = rootDirURI.relativize(file.toURI()).getPath() 
} 

VS

File file, URI rootDirURI 
for() { 
    String rootDirPath = rootDirURI.getPath().substring(1); // cut the first slash 
    rootDirPath = rootDirPath.replaceAll("/", "\\\\"); // correct windows slashes 
    String finalPath = file.getAbsolutePath().replace(rootDirPath, ""); // clear the root path: relativize 
    blabla = finalPath.replace("\\", "/"); // slashes 
} 

好了第一个for循环运行长则2分钟和不到2秒,第二个跑......文件通过UNC路径加载,但是这个for循环是在Files.walkFileTree被执行之后。我在我的文件系统中创建了符号链接,其目标为UNC路径,如\\ 192.168.1.x \ public \第一部分加载ArrayList中的所有内容,第二部分将某些操作(上面的代码for循环)应用于该ArrayList中的文件。

这是否意味着相对性能差或toURI方法?

回答

2

正如@Thomas指出的那样,Path.relativize()确实不仅仅是一个简单的字符串替换。

但是在这种特殊情况下,当它试图确定您的文件是否是目录时,您拥有的瓶颈可能是File.toURI(),因为它涉及文件系统访问。

E.g.下面的测试代码:

ArrayList<File> files = ...; 
URI rootURI = base.toURI(); 
for(File ff : files) { 
    String relative = rootURI.relativize(ff.toURI()).getPath(); 
} 

68993毫秒当应用到100000页的文件数组我的机器上运行。

而且根据jvisualvm,它花费了大部分时间的

java.io.UnixFileSystem.getBooleanAttributes0()

本地方法里面。

enter image description here

可以追溯到File.toURI() -> File.isDirectory()

的等效代码URI对象

ArrayList<URI> files = ...; 
URI rootURI = base.toURI(); 
for(URI ff : files) { 
    String relative = rootURI.relativize(ff).getPath(); 
} 

阵列上运行了短短毫秒内完成,即几乎〜20倍更快。

2

它可能都是。如果您查看两种方法的源代码(URI.relativize(URI),File.toURI()),您会看到许多检查,转换和解析正在进行。由于这些方法需要处理大量不同的输入,并且仍然具有某种容错性,因此需要执行这些操作。

如果您确信文件路径已被清理,规范化,正确等,您可以跳过所有这些检查和转换,因此可以通过一些字符串操作完成。