2017-02-15 4 views
2

나는 100 000 개가 넘는 파일을 반복하고 상대 경로를 일부 루트 디렉토리로 가져오고 코드는 작동하지만 느리지 만 다른 코드와 비교할 때 속도가 느립니다 (이상한 코드이지만 빠릅니다).자바 파일 relativize 메소드 성능

는 원래 코드가 여기에 있습니다 : 글쎄 루프에 대한 첫 번째

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

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 
} 

이상 다음 2 분 적은 다음 2 초 두 번째 실행을 실행 ... 파일이 UNC 경로를 통해로드되지만 for 루프는 Files.walkFileTree가 실행 된 후입니다. \\ 192.168.1.x \ public \ something과 같은 UNC 경로를 타겟으로하는 파일 시스템에 심볼릭 링크를 만들었습니다. 첫 번째 부분은 ArrayList의 모든 항목을로드하고 두 번째 부분은 ArrayList의 파일에 대한 일부 작업 (코드 루프 위)을 적용합니다.

성능이 저조한가 아니면 상대방이 상대 화하는 것입니까?

답변

2

@Thomas가 이미 언급했듯이 Path.relativize()은 단순한 문자열 교체 이상의 기능을 제공합니다.

그러나이 특별한 경우에 병목 현상은 아마도 File.toURI() 일 것입니다. 이는 파일 시스템이 디렉토리인지 여부를 결정할 때 파일 시스템 액세스를 포함하기 때문입니다.

예. 다음 테스트 코드 :

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

100000 개 파일의 배열에 적용될 때, 내 컴퓨터에서 실행 68,993 MS했다.

는 그리고 jvisualvm에 따르면,이

java.io.UnixFileSystem.getBooleanAttributes0()

네이티브 메소드 안에이 대부분의 시간을 보냈다. URI 객체

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

의 배열에 운영 File.toURI() -> File.isDirectory()

동등한 코드로 다시 추적 할 수 있습니다

enter image description here

즉이었다 완료하는 데 단지 밀리했다 거의 ~ 20 번 빨라집니다.

2

아마도 둘 다 같습니다. 두 가지 방법 (URI.relativize(URI), File.toURI())의 소스 코드를 살펴보면 많은 수표, 변환 및 구문 분석이 진행되는 것을 볼 수 있습니다. 이러한 방법은 다양한 입력에 대해 작업해야하며 여전히 내결함성이 있어야하므로 이러한 작업을 수행해야합니다.

파일 경로가 이미 위생, 정규화, 수정 등의 문제가 있다고 확신하는 경우 모든 검사와 변환을 건너 뛸 수 있으므로 몇 가지 문자열 작업 만 수행하면됩니다.