안녕하세요.

처음으로 글을 적어 봅니다.

 

최근에 성능을 조금이라도 더 쥐어 짜내야 하는 앱을 하나 개발하고 있어서

개인적으로 궁금한 점이 많아 이것저것 검색도 해보고 실험도 해본 결과를 간단히 공유하려고 합니다.

(게시판 성격에 잘 맞는지 모르겠습니다. ^^)

 

사실 프로그래밍에 있어서 기본일 수도 있고, 반대로 틀린 점도 있을 수 있습니다...

제 수준에서 적은 것이니 몇몇 분이라도 참고가 되셨으면 좋겠습니다.

혹시 잘못된 사실이나 다른 의견이 있으시면 답글 부탁드립니다. 제게도 많은 도움이 될 듯 합니다. ^-^

 

결론부터 정리하겠습니다.

같은 중간 계산 결과가 2번 이상 반복 사용되는 경우는 무조건 임시 변수를 사용하면 손해 볼것은 별로 없습니다.

 

실질적인 예를 하나 들어보겠습니다.

Android 개발하다보면 다음과 같은 코드를 빈번하게 사용할 수 있습니다.

(아래는 View class를 확장하여 커스텀 view를 만들다가 나오는 코드입니다)

 

canvas.drawRect(getWidth() - length, 0, getWidth(), getHeight(), paint);

 

(View 오른쪽을 기준으로 length 길이만큼 사각형을 그려주는 예입니다.)

 

문제는, 위의 코드에서 getWidth()를 두번 호출하고 있는데 이것을 임시 변수에 저장하는 것이 좋을까요? 아닐까요? 입니다.

 

그러니까...

 

1)

canvas.drawRect(getWidth() - length, 0, getWidth(), getHeight(), paint);

 

2)

final int width = getWidth();

canvas.drawRect(width - length, 0, width, getHeight(), paint);

 

1)번을 쓸지...

아니면 2)번을 쓸지 고민이 된다는 겁니다.

 

중간 계산이 굉장히 복잡하다거나,

getWidth()를 코드내에서 한 10번쯤 쓴다고 하면

고민하지 않고 임시 변수를 쓰겠지만...

 

위와 같은 경우는 왠지 getWidth()라는 함수의 연산이 그리 복잡할 것 같지는 않고,

코드내에서도 2번 밖에 등장하지 않는데,

지역변수를 하나 더 선언하는게 오히려 느리지는 않을까? 고민이 될 수 있습니다.

 

그래서 직접 테스트를 해보았습니다.

오드로이드, 옵티머스 2X 등 여러 기기에서...

 

오드로이드 기준으로 수백만회 (몇회인지 까먹었습니다) 반복 연산한 결과를 정리하면 아래와 같습니다.

 

- 성능 Test 1 -

매우 간단한 연산을 두 번만 사용했습니다.

 

public int compute1(int a, int b) {
    final int minus = a - b;
    return (minus - 2) * (minus + 2);
}

 

public int compute2(int a, int b) {
    return (a - b - 2) * (a - b + 2);
}

 

compute1 평균: 362 ms

compute2 평균: 361 ms

 

별 차이 없습니다.

 

- 성능 Test 2 -

매우 간단한 연산을 여러번 사용했습니다.

 

public int compute1(int a, int b) {
    final int minus = a - b;
    return (minus - 2) * (minus + 2) * (minus + 10) * (minus - 10) * (minus + 100);
}

 

public int compute2(int a, int b) {
    return (a - b - 2) * (a - b + 2) * (a - b + 10) * (a - b - 10) * (a - b + 100);
}

 

compute1 평균: 553 ms

compute2 평균: 631 ms

 

예상했던데로 임시 변수를 쓰는 쪽이 더 빠릅니다.

 

- 성능 Test 3 -

간단한 getter 메소드 사용.

(getMember() 함수는 아무 연산없이 private member를 반환하기만 합니다)

 

public int compute1(int a, int b) {
    final int member = getMember();
    return (member - 2) * (member + 2);
}

 

public int compute2(int a, int b) {
    return (getMember() - 2) * (getMember() + 2);
}



compute1 평균: 552 ms

compute2 평균: 694 ms

 

이 경우에도 임시 변수를 쓰는 쪽이 더 빠릅니다.

 

- 성능 Test 4 -

Member 직접 access

 

public int compute1(int a, int b) {

    final int m = this.member;

    return (m - 2) * (m + 2);

}


public int compute2(int a, int b) {
    return (this.member - 2) * (this.member + 2);

}

 

compute1 평균: 346 ms

compute2 평균: 364 ms

 

심지어 이런 경우에도 임시 지역 변수를 쓰는 쪽이 약간 더 빠릅니다.

 

 

- 결론 -

 

사실 이렇게 까지 성능을 짜낼 필요가 있나 싶기는 하지만...

 

수행속도 면에서 봤을 때, 항상 임시 변수를 써서 손해볼 것은 없어 보입니다.

 

최소한 "지역 변수 할당의 (속도적) 비용이 오히려 더 크지는 않을까?" 하는 걱정은 붙들어 매셔도 될 듯 합니다.