편안한 마음으로 LinkedList를 사용하면 휴식을 취할 수 있어요.
두루뭉술하게 말하다
목록 구조의 데이터에 대해 무작위로 접근할 수 없습니다.오빠와의 약속!
발단
몇 년 전 다른 부서의 지원을 받아 제작된 자바 시스템은 조금 더 큰 데이터가 삽입되면 느릴 테니 도와주세요.
조회와 색인을 살펴봤으면 좋겠군... 코를 파면서 지원해.
처리 내용
느린 부분의 처리는 다음과 같다.
몇 년 전 다른 부서의 지원을 받아 제작된 자바 시스템은 조금 더 큰 데이터가 삽입되면 느릴 테니 도와주세요.
조회와 색인을 살펴봤으면 좋겠군... 코를 파면서 지원해.
처리 내용
느린 부분의 처리는 다음과 같다.
네, 이게 다예요.이런 고급스러운 일을 병행하여 처리하는 것은 당연히 할 수 없다.
인프라 조사
처리 중인 서버의 상태를 조사합니다.이번 인프라는 전형적인 3층 3 서버 구성이다.
WEB 서버는 모든 것에 여유가 있습니다.
AP 서버에서 CPU 하나가 부족합니다.
14코어 서버(EC2의 c4.4xlarge)인 만큼 한 CPU가 아무리 노력해도 7%의 사용률을 기록한다는 게 슬프다.
DB 서버는 디스크 로드가 다소 있지만 성능은 충분합니다.
네트워크, 메모리 등도 조사했지만 모든 자원이 남았다.
각종 설정치도 정상이다.
데이터베이스 주변 조사
보시다시피 이것은 거의 INSERT에서만 처리됩니다.
이 때문에 AP의 CPU 부하에 신경을 많이 썼지만, 현장의 모든 이들이 DB 주변에 다양한 문제가 있다고 의심했다.
마지막에 OR 매핑기 밟은 거 아니야?JDBC라는 그리운 경험을 직접 활용하는 목소리도 있다.
그러나 성과가 없어 발끈한 휴일 출근을 결정했다.
들키다
기본으로 돌아가 논리적 처리 시간을 분석하다.
"순환 횟수가 늘어나면서 처리가 무거워진 것 같다"는 증언에 따르면
우리는 순환 횟수와 순환하는 처리 시간 간의 관계를 제기하기로 결정했다.
다음은 분석 결과의 이미지입니다.입력 데이터 양을 변경해 N만건과 2N만건으로 비교했다.
"후반부 줄었어...!"
작은 데이터는 큰 데이터의 앞부분을 잘라낸 것이기 때문에 데이터 내용에 따라 변동하지 않는다.
더 자세히 분석하면 도표 맨 위에 가장 시간이 걸리는 줄은 다음과 같다.
변수data
의 유형은List<MyClass>
이다.MyClass record = data.get(i);
나는 이것 때문에 간담이 서늘해졌다.오직 리스트에게서 요소를 얻는 것만은 매우 느리다.
누군가가 입을 열었다.
'링크드 리스트 아니에요?'
링크드리스트 2N만점의 N만건을 꺼내는 데 시간이 많이 걸렸다.
아마 리스트 크기의 절반을 기준으로 뒷부분의 데이터는 엉덩이부터 접근했을 거예요.
우리를 쉬게 하는 고장은 for문을 확장for문으로 바꾸는 팩스 수준의 변경으로 끝났다.for (int i = 0; i < data.size(); i++) {
MyClass record = data.get(i);
...
}
↓int i = 0;
for (MyClass record: data) {
...
i++;
}
언뜻 보기에 이것은 무슨 차이가 있습니까?변경되었지만 List의 경우 변경 전 랜덤 액세스
변경된 후 (Iterator의) 순서에 따라 접근할 때 데이터 건수가 많을 때 성능에 있어서 구름과 진흙의 차이가 나타난다.
많이 배웠어요.
처음에 확장 for문장을 사용하지 않은 이유는 처리 중에도 i의 값을 사용하고 싶었기 때문이다.
Java에도 파이톤의 enumerate가 있었으면 좋겠는데... (불평)
Reference
이 문제에 관하여(편안한 마음으로 LinkedList를 사용하면 휴식을 취할 수 있어요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/neko_machi/items/d620c4a8958e74df3550
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
보시다시피 이것은 거의 INSERT에서만 처리됩니다.
이 때문에 AP의 CPU 부하에 신경을 많이 썼지만, 현장의 모든 이들이 DB 주변에 다양한 문제가 있다고 의심했다.
마지막에 OR 매핑기 밟은 거 아니야?JDBC라는 그리운 경험을 직접 활용하는 목소리도 있다.
그러나 성과가 없어 발끈한 휴일 출근을 결정했다.
들키다
기본으로 돌아가 논리적 처리 시간을 분석하다.
"순환 횟수가 늘어나면서 처리가 무거워진 것 같다"는 증언에 따르면
우리는 순환 횟수와 순환하는 처리 시간 간의 관계를 제기하기로 결정했다.
다음은 분석 결과의 이미지입니다.입력 데이터 양을 변경해 N만건과 2N만건으로 비교했다.
"후반부 줄었어...!"
작은 데이터는 큰 데이터의 앞부분을 잘라낸 것이기 때문에 데이터 내용에 따라 변동하지 않는다.
더 자세히 분석하면 도표 맨 위에 가장 시간이 걸리는 줄은 다음과 같다.
변수data
의 유형은List<MyClass>
이다.MyClass record = data.get(i);
나는 이것 때문에 간담이 서늘해졌다.오직 리스트에게서 요소를 얻는 것만은 매우 느리다.
누군가가 입을 열었다.
'링크드 리스트 아니에요?'
링크드리스트 2N만점의 N만건을 꺼내는 데 시간이 많이 걸렸다.
아마 리스트 크기의 절반을 기준으로 뒷부분의 데이터는 엉덩이부터 접근했을 거예요.
우리를 쉬게 하는 고장은 for문을 확장for문으로 바꾸는 팩스 수준의 변경으로 끝났다.for (int i = 0; i < data.size(); i++) {
MyClass record = data.get(i);
...
}
↓int i = 0;
for (MyClass record: data) {
...
i++;
}
언뜻 보기에 이것은 무슨 차이가 있습니까?변경되었지만 List의 경우 변경 전 랜덤 액세스
변경된 후 (Iterator의) 순서에 따라 접근할 때 데이터 건수가 많을 때 성능에 있어서 구름과 진흙의 차이가 나타난다.
많이 배웠어요.
처음에 확장 for문장을 사용하지 않은 이유는 처리 중에도 i의 값을 사용하고 싶었기 때문이다.
Java에도 파이톤의 enumerate가 있었으면 좋겠는데... (불평)
Reference
이 문제에 관하여(편안한 마음으로 LinkedList를 사용하면 휴식을 취할 수 있어요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/neko_machi/items/d620c4a8958e74df3550
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
MyClass record = data.get(i);
for (int i = 0; i < data.size(); i++) {
MyClass record = data.get(i);
...
}
int i = 0;
for (MyClass record: data) {
...
i++;
}
처음에 확장 for문장을 사용하지 않은 이유는 처리 중에도 i의 값을 사용하고 싶었기 때문이다.
Java에도 파이톤의 enumerate가 있었으면 좋겠는데... (불평)
Reference
이 문제에 관하여(편안한 마음으로 LinkedList를 사용하면 휴식을 취할 수 있어요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/neko_machi/items/d620c4a8958e74df3550텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)