카테고리 없음

코드 네 줄에 20만원 - 속도 10배 상승

KyeongRok Kim 2023. 12. 29. 10:12

다음 튜닝 전 코드를 보고 바로 문제점을 찾을 수 있나요? 저는 이 코드 때문에 저는 하루를 꼬박(8시간) 사용했습니다. 이 문제를 애초에 알고 만들어내지 않았다면 쓰지 않았을 시간입니다. 제 하루 일당이 20만원쯤 되는데 20만원을 날린셈입니다. 아니면 하루를 출근 안해도 되는 것이죠 ㅜㅜ

 

저는 이 문제를 DB를 튜닝 하거나 Redis등을 쓰거나 클라우드에서 CPU와 메모리 개수를 조정해서 풀려고 했습니다. 이 의사결정을 했다면 훨씬 비용이 많이 들었을 것입니다.

 

튜닝 전

이 코드는 아래 첨부한 모양의 차트를 만들어내는 코드의 일부 입니다. List<Monitoring>에 있는 데이터를 집계해서 차트를 그릴 때 차트의 컬럼명을 만들 때 씁니다.

List<Monitoring> monitorings = monitorings();

for (int i = 0; i < monitorings.size(); i++) {
    long timestamp = monitorings.get(i).getMonitoredAtAsTimestampHm();
    // 최소 타임스탬프 찾기
    if (timestamp < minTimestamp) {
        minTimestamp = timestamp;
    }
    // 최대 타임스탬프 찾기
    if (timestamp > maxTimestamp) {
        maxTimestamp = timestamp;
    }
    String machineId = monitorings().get(i).getMachine().getId();
    if(!machineIdxMap.containsKey(machineId)){
        machineIdxMap.put(machineId, machineIdx++);
    }
    if(!machineNameMap.containsKey(machineId)){
        String machineName = monitorings().get(i).getMachine().getName();
        machineNameMap.put(machineId, machineName);
    }
}

 

 

 

생성:755 millis
헤더:583 millis
데이터:697 millis

 

위 시간은 위 코드를 사용하는 3개의 메소드의 실행 시간을 측정한 데이터입니다. 데이터는 5000개 기준입니다. 이 로직이 포함 되어있는 코드들의 실행 시간을 출력해보면 각각 0.7, 0.6, 0.7초 정도 걸렸고 합쳐보면 2초 정도가 됩니다. API의 응답 속도가 2초라면 매우 느린 것입니다.

 

 이 코드 때문에 API의 응답 속도가 2초 ~ 10초까지 걸렸습니다.

심지어 조건에 따라 10초 가량 걸리는 경우도 있습니다.

 

 

어떤 문제인지 찾아 보셨나요? 여기에서 문제가 되는 코드는 monitorings.get(i) 입니다.  List.get(i)의 속도가 느렸던 것입니다. 아마도 .get(i)의 속도가 O(1)이 아니라 O(N)인 것 같은데 데이터 개수가 5천개쯤 되면 .get(i)를 할 때마다 N번씩 순차 접근을 하는 것 같습니다.

 

튜닝 후

그래서 .get(i)를 한번만 쓰도록 처리 하니 속도가 10배 빨라졌습니다. 2초 걸리던 것이 0.2초대로 줄었습니다.

List<Monitoring> monitorings = monitorings();

for (int i = 0; i < monitorings.size(); i++) {
    Monitoring monitoring = monitorings.get(i);                 // 수정
    long timestamp = monitoring.getMonitoredAtAsTimestampHm();  // 수정
    // 최소 타임스탬프 찾기
    if (timestamp < minTimestamp) {
        minTimestamp = timestamp;
    }
    // 최대 타임스탬프 찾기
    if (timestamp > maxTimestamp) {
        maxTimestamp = timestamp;
    }
    String machineId = monitoring.getMachineId();		    // 수정
    if(!machineIdxMap.containsKey(machineId)){
        machineIdxMap.put(machineId, machineIdx++);
    }
    if(!machineNameMap.containsKey(machineId)){
        String machineName = monitoring.getMachine().getName(); // 수정
        machineNameMap.put(machineId, machineName);
    }
}

 

생성:135 millis
헤더:4 millis
데이터:42 millis

 

Loop에서 List.get(i)를 사용할때는 주의 하시기 바랍니다.

 

 

API호출 속도도 ms단위로 나오면서 괜찮아졌습니다.

 

end.

728x90