2012-03-14 1 views
5

SHA-1 해시를 계산해야하는 Java 라이브러리를 작성 중입니다. 일반적인 작업을 수행하는 동안 JVM은 sun.security.provider.SHA.implCompress에 약 70 %, java.util.zip.Inflater.inflate에 10 %, sun.security.provider.ByteArrayAccess.b2iBig64에 2 %를 사용합니다. (NetBeans 프로파일 러에 따름)최대 SHA-1 해시 성능 팁 (Java)

관련 검색 결과를 얻으려면 Google 검색 키워드를 제대로 볼 수 없습니다. SHA-1 해시 알고리즘에 익숙하지 않습니다. SHA-1 MessageDigest에서 성능을 극대화하려면 어떻게해야합니까? 소화해야 할 특정 청크 크기가 있습니까, 아니면 시도해야하는 특정 크기의 배수입니까?

당신이 묻고 생각하고 몇 가지 질문에 대답하려면 : 나는 파일 ( MessageDigest.update를) 읽을 바이트가 한 번만 소화되도록

  • 예, 내가 소화하고있다.
  • SHA-1 다이제스트는 일반적으로 zlib/inflated 일 필요가있는 파일의 체크섬으로 사용됩니다.
  • 아니요, 다른 해시를 사용할 수 없습니다.
  • 예, zlib은 이미 체크섬을 사용하고 있지만 외부 요구 사항은 SHA-1 해시의 사용을 지정합니다. 나는 좋은 이유를 생각해 낼 수 없다 (+1 할 수 있다면) :-)
+2

이 작업을 수행해야하는 로컬 컴퓨터에서 IO 인 경우 SSD 디스크에 투자하는 것이 좋습니다. 실제로 HDD에서 파일을 읽는 것이 병목 현상입니다. –

+0

I/O를 최적화 할 수있는 작업을 이미 수행했습니다. 이미 다양한 IO 최적화를 조사한 결과, IO는 소화만큼의 시간이 소요된다고합니다.나는 IO로 더 잘 할 수 없다는 것을 확신한다. –

+2

Java는 C/C++과 비교해 보면 속도가 느리지 만 어떤 작업에서는 더 빠르다. 알고리즘의 C/C++ 구현에 액세스 할 수있는 경우 비교를 수행하십시오. java가 상당히 느린 경우에는 개선의 여지가 있지만 거의 같으면 개선 가능성이 적습니다. (내가 할 수학이 많았을 때 나는 C와 Ds와 비교해 봤는데, 자바 버전이 가장 빠르다고 판명되었다.) –

답변

1

SHA-1의 블록 크기는 64 바이트입니다. 따라서 그 배수가 가장 좋습니다. 그렇지 않으면 구현시 부분 블록을 버퍼로 복사해야합니다.

멀티 코어 컴퓨터에서 실행 중이십니까? java.util.concurrent.SynchronousQueue과 같은 것을 사용하여 zlib 압축 해제 및 SHA-1 해시를 별도의 스레드에서 실행할 수 있으며 압축 해제 된 각 64 바이트 블록을 한 스레드에서 다른 스레드로 넘겨줍니다. 그렇게하면 다른 코어가 다음 블록의 압축을 풀면서 하나의 코어가 한 블록을 해싱 할 수 있습니다.

(일부 스토리지 용량을 가진 다른 BlockingQueue 구현 중 하나를 시도해 볼 수는 있지만 많은 도움이 될 것이라고 생각하지 않습니다. 해싱보다 훨씬 빠르기 때문에 zlib 스레드가 대기열에 넣은 다음 SynchronousQueue처럼 각 새 블록을 넣으려고 기다려야합니다.)

내가 이미 I/O를 최적화했지만 비동기 I/O를 사용하고 있다고하셨습니까? 최대 성능을 위해 한 블록을 해시하고 싶지 않고 을 입력 한 다음에 다음 블록을 읽으라고 요청하면 OS가 다음 블록을 읽도록 요청한 다음 디스크가 사용 중일 때 이미 가지고있는 블록을 해쉬하려고합니다 다음. 그러나 OS가 이미 일부 미리 읽기 기능을 제공 할 수도 있으므로 큰 차이는 없습니다.

하지만 그 이상으로, 암호화 해시 기능은 복잡한 것입니다. 그냥 달릴 시간이 있습니다. 더 빠른 컴퓨터가 필요할 수도 있습니다. :-)

+0

zlib에 사용 된 CRC 위에 암호화되지 않은 해시 대신 암호화되지 않은 해시를 체크섬으로 사용하면 좋을 것입니다. 라이브러리의 성능을 목표로하지 않는다면 비동기 입출력이 좋을 것입니다. 많은 파일을 검사하는 특정 테스트의 성능이 아닙니다. 그러나 필자는 라이브러리를보다 멀티 스레드 친화적으로 설계 할 수있는 방법을 생각하게되었습니다. 체크섬 계산에 파일 I/O보다 시간이 오래 걸리므로, 내가 작업하고있는 파일을 사용하는 프로그램의 디자이너가 이상한 선택을하게 된 것에 놀랐다. –

+0

음, 아마 그들은 아마도 충돌 저항을 원한다. 해시 제공; 그렇지 않으면 zlib가 이미 CRC보다 더 많은 부가 가치가 없을 것입니다. – Wyzard

+0

순차적 인 파일 액세스가 현대의 하드 드라이브에서 느린 것은 아닙니다. 나는 전체 드라이브에 평균 100MB/초 이상의 평균 5900rpm "초록색"드라이브를 가지고 있으며 가장자리에서 최대 150MB/초입니다. SHA-1과 같은 비교적 느린 알고리즘과 비교하면 나쁘지 않습니다. – Wyzard

0

파일 매핑을 메모리 매핑 파일로 전환 해 보았습니까? 성능은 일반 IO 및 NIO보다 훨씬 빠릅니다.

+0

SHA-1 다이제스트는 일반적으로 zlib/inflated 일 필요가있는 파일의 체크섬으로 사용됩니다. 실제로 체크섬을 계산하기 전에 대부분의 파일을 확장해야하기 때문에'DirectByteBuffer'를 사용하고 있습니다. 프로파일 러에서 호출 스택을 보면 다이제스트 엔진은 배열이없는 버퍼 (힙이 아닌 버퍼)를 보냈을 때 직접 버퍼의 내용을 새로운 로컬 힙으로 복사하는 메서드를 사용합니다. 원시 바이트 배열 실제로 운영 체제 및 CPU L1 캐시 크기에 따라 기본 바이트 버퍼를 최적화합니다. JVM에 따라 다름. –

+0

태양의 JRE가'MappedByteBuffers'로 작업 한 소화조를 제공하면 좋을 것입니다. 도서관과 함께 배포 할 수있는 것을 알고 있습니까? java.util.zip이'MappedByteBuffer's로 작업하면 더 좋을 것입니다. 제 말은 이미 네이티브 메모리에서 작동합니다! 어쩌면 나는 RFE를 넣을거야 ... –

1

아마도 C로 작성된 원시 코드를 호출 할 수 있습니다. 사용 가능한 수퍼 최적화 SHA1 라이브러리가 있어야합니다.

+0

Ewww ... 많은 일처럼 들린다. 소화조에 적당한 크기의 완충액을 보내야할지 모르겠습니다. 그게 정말로 내가 알아 내려고하는 것입니다. –