2009-06-23 2 views
5

저는 데이터가 플랫 파일에 저장되는 (database-ish) 프로젝트를 작업 중입니다. 읽기/쓰기를 위해서 나는 RandomAccessFile 클래스를 사용하고 있습니다. 멀티 스레딩에서 무엇이든 얻을 수 있으며 각 스레드에게 각각 RandomAccessFile의 인스턴스를 제공합니까, 아니면 하나의 스레드/인스턴스도 마찬가지로 빠릅니까? 독서를하거나 쓰기 만 할 수있는 인스턴스를 만들 수 있으므로 읽기/쓰기에 어떤 차이가 있습니까?RandomAccessFile 도움말 성능이있는 다중 스레드를 사용합니까?

답변

0

상당히 일반적인 질문입니다. 기본적으로 여러 스레드를 사용하면 하드 드라이브가 더 빨리 진행되지 않습니다. 대신 동시 요청을 수행하면 속도가 느려질 수 있습니다.

디스크 하위 시스템 인 esp IDE, EIDE, SATA는 순차적으로 가장 빠르게 읽고 쓸 수 있도록 설계되었습니다.

+0

고마워, 내가 원하는 대답;) – drRoflol

+0

더 빠른 하드 드라이브를 원하면 SSD 드라이브를 사용하십시오. 그것은 당신이하는 일에 따라 회전하는 디스크보다 5 배에서 30 배 빠릅니다. 또한 그들은 적은 전력을 사용합니다. –

+7

그게 사실이 아닙니다. 대부분의 디스크는 기본 명령 대기열을 지원합니다. http : // www.seagate.com/content/pdf/whitepaper/D2c%5Ftech%5Fpaper%5Fintc-stx%5Fsata%5Fncq.pdf –

3

RandomAccessFile이 동기화되어 있으므로 인스턴스를 공유하면 하나의 스레드 만 실행할 수 있습니다. Oops, RandomAccessFile은 동기화되지 않으며 스레드 간의 공유가 전적으로 안전하지 않습니다. 특히 운영 체제의 불규칙성이 관련되어있는 경우 동일한 스레드 변경 가능 데이터 구조에 액세스하는 스레드가 여러 개있을 때 조심해야합니다.

RandomAccessFile의 작은 조작은 무시 무시하게 느립니다.

최대 성능을 얻으려면 java.nio을 곧바로 사용하는 것이 좋습니다. 그러나 빠르게 작동하기 전에 작동하는 것이 좋습니다. OTOH, 성능을 염두에 두십시오.

+0

또는 nio 또는 심지어 nio2 (또는 지금받을 이름) – OscarRyz

+0

멀티 스레드로가는 경우 각 스레드에게 자체 인스턴스를 제공하고 있습니다. 하지만 할 수있는 IO는 어쨌든 똑같을 것입니다. 그렇죠? 그래서 나는 그것을 중요시하지 않을 것이며 어쩌면 시스템을 느리게 할 수도 있습니다. O 또한, "먼저 작동하게하고 성능에 대해 걱정하십시오"라는 것을 알게되었습니다. 어쨌든 고마워요 : D – drRoflol

+2

오스카 : 오타. "NIO"와 "NIO2"는 모두 java.nio입니다. NIO.2라는 용어는 "더 많은 NIO 기능"으로 바뀌 었습니다. 왜냐하면 법률 팀은 NIO.2를 사용하기 위해 다른 검색을하고 싶어했기 때문에 합병이 끝나면 가치가 없었습니다. –

3

JavaDoc에서 RandomAccessFile을 보면 클래스 자체가 동기화되지 않습니다. 읽기 및 쓰기 작업에 동기 모드를 사용할 수있는 것으로 보입니다. 비록 동기화 된 모드를 사용하지 않는다하더라도 당신은 사소한 것과는 거리가 먼 자기 자신을 읽고 쓰는 것에 대한 자물쇠를 관리해야 할 것입니다. 다중 쓰레드를 사용할 때 java.io가 똑같은 경우도 마찬가지입니다.

데이터베이스에서 이런 종류의 멀티 스레드 추상화를 제공하므로 데이터베이스를 사용하는 것이 좋습니다. Java 또는 log4j에서 사용 가능한 syslog 옵션을 볼 수도 있습니다.

+0

읽기/쓰기 작업에 대한 잠금은 문제가되지 않습니다. 그 내용은 다음과 같습니다. – drRoflol

+0

모드는 동기화 * 동기화되지 않습니다. 즉, 데이터가 디스크에 커밋 될 때까지 메서드 호출이 반환되지 않습니다. seek() 호출과 read() 호출 사이에서 다른 스레드가 seek()을 다른 위치로 호출 할 수 있기 때문에 스레드 안전을 보장하지 않습니다. –

1

NIO를 사용하여 플랫 파일을 메모리 맵핑하는 옵션이 있습니다. 이 경우 OS 메모리 관리자는 파일의 in-out 섹션을 이동시키는 책임을집니다. 작성자에게 영역 잠금을 적용 할 수도 있습니다.

9

C++ 개발 경험으로 대답 : 예, 여러 스레드를 사용하면 파일을 읽을 때 성능이 향상 될 수 있습니다. 이것은 순차 및 연속 액세스 모두에 적용됩니다. 나는 실제 병목 현상이 항상 다른 곳에서 발견 되었음에도 불구하고 이것을 한 번 이상 입증했습니다.

디스크 액세스의 경우 스레드는 디스크 작업이 완료 될 때까지 일시 중단됩니다. 그러나 오늘날 대부분의 디스크는 기본 명령 대기열 see (SAS) 또는 Segate (SATA) (대부분의 RAID 시스템뿐만 아니라)을 지원하므로 사용자가 요청한 순서대로 요청을 처리 할 필요가 없습니다.

따라서 4 개의 파일 청크를 순차적으로 읽으면 프로그램은 첫 번째 청크를 기다린 다음 두 번째 청크를 요청해야합니다. 4 개의 쓰레드가있는 4 개의 청크를 요청하면, 한번에 모두 반환 될 수 있습니다. 이러한 종류의 최적화에는 한계가 있지만 작동합니다 (여기에는 C++에서만 경험이 있지만). 여러 스레드가 순차 읽기 성능을 100 % 이상 향상시킬 수 있다고 측정했습니다.

11

이제 나는 아래의 코드로 벤치마킹을했습니다. (실례합니다. 코드는 명령 줄 인수로 전달 된 스레드 수와 함께 5MB 텍스트 파일을 읽습니다.

업데이트 :

결과는 명확 여러 스레드가 항상 프로그램 속도를 보여 그것은 내 마음에 와서, 즉 파일 캐싱은 여기에 아주 중요한 역할을합니다. 그래서 나는 testdata 파일의 복사본을 만들고, 재부팅하고 각각의 실행마다 다른 파일을 사용했습니다. 아래에 업데이트 된 결과 (괄호 안에 이전 항목). 결론은 동일하게 유지됩니다. 0.61s (0.61s)

  • 2 개 스레드 : 초에

    런타임

    시스템 A

    • 1 실 (4 10K SAS 듀얼 쿼드 코어 제온 실행 XP 64은 RAID 5에서 드라이브) : 0.44s (0.43s)
    • 쓰레드 4 : 0.31s (0.28s) (빠른)
    • 8 스레드 : 0.53s (0.63s)
    ,536,913 63,210

    기계 B (한 조각 2.5 인치 드라이브에 XP를 실행하는 듀얼 코어 노트북)

    • 1 실 : 0.98s (1.01s)
    • 2 스레드 : 0.67s (0.61s) (빠른)
    • 4 스레드 : 1.78s (0.63s)
    • 8 스레드 : 2.06s (0.80s)

    소스 코드 (윈도우) :

    ,
  • +0

    이 데이터를 공유해 주셔서 감사합니다. 나는 후자가 얼간이와 싸우는 경향이 있기 때문에 특히 손으로 손을 흔드는 데 하드 번호를 선호한다. –

    +0

    고마워요! Awesome work;) 미안하지만, 나는 C++ 사람이 아니지만, 당신이 윈도우즈 머신에 있다는 것을 이해합니다. – drRoflol

    +0

    예, Windows. 왜? –

    1

    나는 모든 대답에 대한 성능을 이야기 놀라지,하지만 모두 성능 특성이있는 반면, 아무도, 처리량에서이 지연 구분하지 않습니다. @RED SOFT ADAIR has shown과 같이 여러 스레드를 사용하여 추가 처리량을 얻을 수는 있지만 대기열을 트레이드 오프 (trade off)합니다 (특히 기본 명령어 순서 지정의 경우).

    관련 문제