2013-04-10 2 views
3

파일의 해시 성능/최적화 가져옵니다. 나는 몇 십만 파일을 어디서나 파일을 백업 한 줌 사이에서 (5기가바이트 + 파일 당 최대 몇 KB 어디서나) 임의의 파일 크기로 구성된 데이터 (100기가바이트 +)의 대형 세트를 해시하는 프로그램이있다. 모든 자바 지원해야나는 가능한 한 빨리 파일의 해시를 얻으려고

프로그램 알고리즘 (MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512)를 지원.

은 현재 내가 사용

/** 
* Gets Hash of file. 
* 
* @param file String path + filename of file to get hash. 
* @param hashAlgo Hash algorithm to use. <br/> 
*  Supported algorithms are: <br/> 
*  MD2, MD5 <br/> 
*  SHA-1 <br/> 
*  SHA-256, SHA-384, SHA-512 
* @return String value of hash. (Variable length dependent on hash algorithm used) 
* @throws IOException If file is invalid. 
* @throws HashTypeException If no supported or valid hash algorithm was found. 
*/ 
public String getHash(String file, String hashAlgo) throws IOException, HashTypeException { 
    StringBuffer hexString = null; 
    try { 
     MessageDigest md = MessageDigest.getInstance(validateHashType(hashAlgo)); 
     FileInputStream fis = new FileInputStream(file); 

     byte[] dataBytes = new byte[1024]; 

     int nread = 0; 
     while ((nread = fis.read(dataBytes)) != -1) { 
      md.update(dataBytes, 0, nread); 
     } 
     fis.close(); 
     byte[] mdbytes = md.digest(); 

     hexString = new StringBuffer(); 
     for (int i = 0; i < mdbytes.length; i++) { 
      hexString.append(Integer.toHexString((0xFF & mdbytes[i]))); 
     } 

     return hexString.toString(); 

    } catch (NoSuchAlgorithmException | HashTypeException e) { 
     throw new HashTypeException("Unsuppored Hash Algorithm.", e); 
    } 
} 

이 파일의 해시를 얻기에 관하여 갈 수있는 더 최적화 된 방법이 있나요? 극단적 인 성능을 찾고 있는데 내가 가장 좋은 방법을 생각해 본지 확실하지 않습니다.

+3

코드를 프로파일 링 했습니까? 대부분의 시간을 어디에 소비합니까? – NPE

답변

5

나는 잠재적 인 성능 개선을 참조하십시오. 하나는 StringBuffer 대신 StringBuilder을 사용하는 것입니다. 소스와 호환되지만 동기화되지 않기 때문에 성능이 향상됩니다. 두 번째 (훨씬 더 중요)는 FileInputStream 대신 FileChanneljava.nio API를 사용하거나 BufferedInputStreamFileInputStream을 입력하여 I/O를 최적화하는 것입니다.

1

어니스트의 답변 외에도 - MessageDigest.getInstance (validateHashType (hashAlgo))이 키는 validateHashType (hashAlgo)을 키로 사용하여 스레드 로컬 해시 맵에 캐시 할 수 있다고 생각합니다. MessageDigest를 만드는 데는 시간이 걸리지 만 Map에서 인스턴스를 가져온 후 처음에 reset() 메소드를 호출하여 다시 사용할 수 있습니다.

java.lang.ThreadLocal의 javadoc을 참조하십시오.

관련 문제