2012-08-31 3 views
0

IO에 관한 연구를하고 있었는데 다음과 같은 버퍼링 기술에 대한 기사를 읽었습니다. 디스크 액세스를 최소화하고 기본 운영 체제에서 작업하기 위해 버퍼링 기술은 모든 읽기 작업으로 디스크에서 직접 데이터를 읽는 대신 청크 방식으로 데이터를 읽는 임시 버퍼를 사용합니다.파일 읽기와 성능 최적화에 관해서

실시 예는 완충제를 사용하지 않고 완충 처리하여 제공 하였다. 버퍼링

try 
{ 
    File f = new File("Test.txt"); 
    FileInputStream fis = new FileInputStream(f); 
    int b; int ctr = 0; 

    while((b = fis.read()) != -1) 
    { 
    if((char)b== '\t') 
    { 
     ctr++; 
    } 
    } 
    fs.close(); 
// not the ideal way 
} catch(Exception e) 
{} 

: 버퍼링없이

try 
{ 
    File f = new File("Test.txt"); 
    FileInputStream fis = new FileInputStream(f); 
    BufferedInputStream bs = new BufferedInputStream(fis); 
    int b; 
    int ctr = 0; 
    while((b =bs.read()) != -1) 
    { 
    if((char)b== '\t') 
    { 
     ctr++; 
    } 
    } 
    fs.close(); // not the ideal way 
} 
catch(Exception e){} 

결론이었다 :

Test.txt was a 3.5MB file 
Scenario 1 executed between 5200 to 5950 milliseconds for 10 test runs 
Scenario 2 executed between 40 to 62 milliseconds for 10 test runs. 

더 그 자바에서이 작업을 수행하는 다른 방법이 있나요? 또는 다른 방법/기법을 사용하여 더 나은 성능을 제공 할 수 있습니까?

+1

코드 서식 지정 ... HORROR! 아니요, 코드를 들여 쓰기 할 수 있습니까? 당신의 코드를 읽으려고 당신을 도우려는 사람들에게 성가시다. 감사! – thatidiotguy

답변

1

참조뿐만 아니라 NIO 및 메모리 매핑 된 파일을 시도 할 수 있습니다? 또는 더 나은 성능을 제공하는 다른 방법/기법?

IO 성능 측면에서 볼 때, 다른 코드를 많이 사용하지 않는 것이 가장 좋습니다. 어쨌든 IO 바인딩이 될 것입니다.

동안 ((b = bs.read())! = -1)

이것은 바이트 단위를 판독하는 것은 매우 비효율적이다. 텍스트 파일을 읽는 경우 대신 BufferedReader을 사용해야합니다. 바이트 배열을 String으로 변환합니다. 또한

BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); 
... 
while ((String line = reader.readLine()) != null) { 
    ... 
} 

이 어떤 IO와 함께, 당신은 항상 시도에 그것을해야/마지막으로 확인 차단 당신이 그것을 닫습니다

FileInputStream fis = new FileInputStream(f); 
BufferedReader reader; 
try { 
    reader = new BufferedReader(new InputStreamReader(fis)); 
    // once we wrap the fis in a reader, we just close the reader 
} finally { 
    if (reader != null) { 
     reader.close(); 
    } 
    if (fis != null) { 
     fis.close(); 
    } 
} 
0

한 번에 데이터 블록을 읽을 수있는 여전히 수 버퍼링 된 입력을 사용하는 것보다 빠르다.

FileInputStream fis = new FileInputStream(new File("Test.txt")); 
int len, ctr = 0; 
byte[] bytes = new byte[8192]; 

while ((len = fis.read(bytes)) > 0) 
    for (int i = 0; i < len; i++) 
     if (bytes[len] == '\t') 
      ctr++; 
fis.close(); 

메모리 매핑을 시도 할 수도 있습니다.

FileChannel fc = new FileInputStream(new File("Test.txt")).getChannel(); 
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 
int ctr = 0; 
for (int i = 0; i < bb.limit(); i++) 
    if (bb.get(i) == '\t') 
     ctr++; 
fc.close(); 

나는 두 가지 옵션이 모두 두 배 빠름을 기대합니다.

+0

고마워. 나는 둘 다 찍은 시간을 꺼내려고하고 알려주지 않을거야, 제발 두 번째 프로그램에서 무슨 일이 일어나고 있는지 조금 나에게 관련된 메모리 매핑 파일 개념을 말해 주시겠습니까 ..이 링크를 통해 http://javarevisited.blogspot.in/2012/01/memorymapped-file-and-io-in-java.html – user1633823

+0

OS가 일부 (또는 모든 파일)을 가져 와서 사실상 매핑합니다. 메모리에. 이 시점에서 데이터가 이미 메모리에 읽혀져 있거나 디스크에 쓰기 가능 상태 인 것처럼 데이터에 액세스 할 수 있습니다. 이렇게하면 데이터를 복사하는 오버 헤드를 크게 줄일 수 있습니다. 또 다른 장점은 백그라운드에서 로딩이 효과적으로 수행된다는 것입니다. OS가 데이터를 작성할 수 있으면 기꺼이 데이터를 플러시 할 필요가 없습니다. –

관련 문제