///
Search
🎯

고정 크기 BufferedReader

태그
JAVA
Celper 업데이트를 위해 여러 라이브러리를 분석하던 중 뜬금없이 “왜?” 라는 의문이 드는 코드를 발견했다.
다음은 fastCSV의 코드에서 내부에 custom Buffer를 사용하는 부분이다.
각설하고 의문은 다음과 같았다. READ_SIZE는 상수이다. 근데 코드를 살펴보면 extendAndReloacate() 즉, buffer를 늘리는 코드가 존재한다. 그럼 READ_SIZE에 변화를 주어 더 많은 데이터를 읽도록 해야 한다고 생각했다. 하지만 코드에서는 고정된 READ_SIZE를 계속 사용한다.
여기서 “왜?” 라는 의문을 가졌다. “도와줘요 GPT” 를 외쳤다.
이유는 다음과 같다. 1. 고정 사이즈를 사용하는 이유는 메모리에 큰 데이터가 과적 될 수 있다. 2. 동일 사이즈 즉, 8192를 계속 읽으면 메모리 히트가 높아진다. 3. 가비지 컬렉션에 부하가 적어진다.
1번은 어느 정도 생각했다. 근데 2와 3은 예상 못했던 부분이다. 참고하면 좋을 것 같다.
private static class CsvBuffer implements Closeable { private static final int READ_SIZE = 8192; // 문제의 상수 private static final int BUFFER_SIZE = READ_SIZE; char[] buf; int len; int begin; int pos; .. private boolean fetchData() throws IOException { if (reader == null) { return false; } if (begin < pos) { // we have data that can be relocated if (READ_SIZE > buf.length - pos) { // need to relocate data in buffer -- not enough capacity left final int lenToCopy = pos - begin; if (READ_SIZE > buf.length - lenToCopy) { // need to relocate data in new, larger buffer buf = extendAndRelocate(buf, begin); } else { // relocate data in existing buffer System.arraycopy(buf, begin, buf, 0, lenToCopy); } pos -= begin; begin = 0; } } else { // all data was consumed -- nothing to relocate pos = begin = 0; } final int cnt = reader.read(buf, pos, READ_SIZE); // 문제의 상수를 사용 if (cnt == -1) { return false; } len = pos + cnt; return true; } private static char[] extendAndRelocate(final char[] buf, final int begin) { final int newBufferSize = buf.length * 2; // 문제의 새로운 Buffer Size if (newBufferSize > Limits.MAX_FIELD_SIZE) { throw new CsvParseException(String.format("The maximum buffer size of %d is " + "insufficient to read the data of a single field. " + "This issue typically arises when a quotation begins but does not conclude within the " + "confines of this buffer's maximum limit.", Limits.MAX_FIELD_SIZE)); } final char[] newBuf = new char[newBufferSize]; System.arraycopy(buf, begin, newBuf, 0, buf.length - begin); return newBuf; } }
Java
복사