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)를 지원하는 언어도 있는데, 성능은 과연 어떨까나?
Reference : https://stackoverflow.com/questions/2426455/javas-varargs-performance
SDK의 로그 설정 코드에는 위와 같이
Object... args
처럼 길이를 무한정 받을 수 있는 vararg가 선언되어 있다. 이를 응용해서Storage
의 키 값을 네임스페이스를 타고 들어가는 것 처럼 가독성을 유지하면서도 실수로 키값의 충돌이 없도록 짜려고 했다. 그래서 다음과 같이Storage.keys
를 정의하고, 이 함수를static import
하여 다음과 같이 사용해보려 했다Stroage.java
BitsoundReceiverStorage.java
그러던 와중 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)를 지원하는 언어도 있는데, 성능은 과연 어떨까나?