Soundlly / Study

0 stars 0 forks source link

Java varargs의 성능에 따른 삽질 #15

Open pjhjohn opened 6 years ago

pjhjohn commented 6 years ago

Reference : https://stackoverflow.com/questions/2426455/javas-varargs-performance

public final class LogCat {
    public static void v(String tag, String format, Object... args);
    public static void d(String tag, String format, Object... args);
    public static void i(String tag, String format, Object... args);
    public static void w(String tag, String format, Object... args);
    public static void e(String tag, String format, Object... args);
}

SDK의 로그 설정 코드에는 위와 같이 Object... args처럼 길이를 무한정 받을 수 있는 vararg가 선언되어 있다. 이를 응용해서 Storage의 키 값을 네임스페이스를 타고 들어가는 것 처럼 가독성을 유지하면서도 실수로 키값의 충돌이 없도록 짜려고 했다. 그래서 다음과 같이 Storage.keys를 정의하고, 이 함수를 static import하여 다음과 같이 사용해보려 했다

Stroage.java

public class Storage {
    public static String key(Object... keys) {
        return TextUtils.join("_", keys);
    }
}

BitsoundReceiverStorage.java

import io.bitsound.common.Storage;
import static io.bitsound.common.Storage.key;

public final class BitsoundReceiverStorage {
    public static final String RECEIVER = "receiver";
    public static final String ADID = "adid";

    @NonNull
    public static String getADID(@NonNull Context context) {
        return Storage.getInstance(context).getString(key(RECEIVER, ADID), DUMMY_HASH);
    }
}

String.join은 Java8에서 추가된 API이기 때문에 안드로이드에서는 Android O(API26) 이상에서 지원되기 때문에 TextUtils.join을 사용하였다.

그러던 와중 RxJava 등 여러 라이브러리에서 굳이 입력 변수 개수를 1개부터 10개까지 굳이 오버로딩하던 것이 생각났고, 당연히 성능 이슈일 것 같았다. Stack Overflow를 보니, 누군가가 이미 간단히 벤치마크를 만들어 두었고, 약 30~60배 정도 느리다는 것을 알게 되었다.

이유인 즉슨, varargs는 문법의 구성 요소가 아니라 Synthetic Sugar이기 때문이다. String...String[]와 동일하게 동작한다. 따라서 varargs를 사용하지 않은 메소드는 JVM에서 함수 호출 시 해당 Method Signature에 등록된 함수 만큼의 메모리 공간을 확보하고 바로 진행하도록 컴파일되는 데 반해 vararg필드는 컴파일 타임이 아닌 런타임에 입력 인자의 개수가 결정되기 때문에, 그 시점에 메모리 배열을 새로 할당해야 하므로 더 느릴 수 밖에 없다.

아무튼, 결국 인자 오버로딩으로 2, 3, 4개의 입력을 받도록 수정했다 ㅎㅎ 아, LogCat함수들은 어차피 디버그 용도기 때문에 그냥 둘 것이다. 편하니까. 느낀점 : 다른 라이브러리 코드를 자주 보자(시간이 나면...).

Q. Python을 비롯한 다른 언어들 중에는 심지어 kwargs(keyword arguments)를 지원하는 언어도 있는데, 성능은 과연 어떨까나?