자바
[성능] 모델셋팅 및 리플렉션 처리..
fromm0
2011. 1. 7. 11:14
# 테스트 환경
1. jdk1.6.0_23
2. 프로파일러 : JProfiler v.5.2.4
# 케이스별 테스트 소스와 프로파일링 결과
1. 모델의 setter메서드로 셋팅
20번 호출에 15,653us 소요됨
2. Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 사용
20번 호출에 21,372us 소요됨
3. Spring의 ReflectionUtils 사용
20번 호출에 13,008us 소요됨
# 정리
1. 순수하게 JDK의 리플렉션을 사용한 테스트 수치는 없음
2. Spring ReflectionUtils < 모델 setter 메서드 < Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 순으로 소요시간이 적음
3. 모델 setter 메서드 방식이 가장 빠를 것으로 짐작했으나, 예상과 다른 결과가 나타남. 좀더 테스트가 필요할 것으로 생각됨
1. jdk1.6.0_23
2. 프로파일러 : JProfiler v.5.2.4
# 케이스별 테스트 소스와 프로파일링 결과
1. 모델의 setter메서드로 셋팅
public static JaxbMessage validateUrlParam(BindingResult result) {
if (result.hasErrors()) {
JaxbMessage message = getDefaultMessage();
LOGGER.info("바인딩결과 : {} ", result);
JaxbError error = new JaxbError();
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
error.setCode(errorCode);
error.setMsg(ValidationErrorMessageAccessor.getMessages().get(errorCode));
LOGGER.info("{}", error);
message.setError(error);
return message;
}
return null;
}
if (result.hasErrors()) {
JaxbMessage message = getDefaultMessage();
LOGGER.info("바인딩결과 : {} ", result);
JaxbError error = new JaxbError();
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
error.setCode(errorCode);
error.setMsg(ValidationErrorMessageAccessor.getMessages().get(errorCode));
LOGGER.info("{}", error);
message.setError(error);
return message;
}
return null;
}
20번 호출에 15,653us 소요됨
2. Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 사용
public M validateUrlParamOld(M message, E error, String service, String type, String version, BindingResult result) {
if (result.hasErrors()) {
LOGGER.info("바인딩결과 : {} ", result);
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
try {
PropertyDescriptor[] errorPds = BeanUtils.getPropertyDescriptors(error.getClass());
for (PropertyDescriptor desc : errorPds) {
if ("code".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(error, errorCode);
}
if ("msg".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(error, ValidationErrorMessageAccessor.getMessages().get(errorCode));
}
}
PropertyDescriptor[] messagePds = BeanUtils.getPropertyDescriptors(message.getClass());
for (PropertyDescriptor desc : messagePds) {
if ("error".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, error);
}
if ("service".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, service);
}
if ("type".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, type);
}
if ("version".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, version);
}
}
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
return message;
}
return null;
}
if (result.hasErrors()) {
LOGGER.info("바인딩결과 : {} ", result);
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
try {
PropertyDescriptor[] errorPds = BeanUtils.getPropertyDescriptors(error.getClass());
for (PropertyDescriptor desc : errorPds) {
if ("code".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(error, errorCode);
}
if ("msg".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(error, ValidationErrorMessageAccessor.getMessages().get(errorCode));
}
}
PropertyDescriptor[] messagePds = BeanUtils.getPropertyDescriptors(message.getClass());
for (PropertyDescriptor desc : messagePds) {
if ("error".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, error);
}
if ("service".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, service);
}
if ("type".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, type);
}
if ("version".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, version);
}
}
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
return message;
}
return null;
}
20번 호출에 21,372us 소요됨
3. Spring의 ReflectionUtils 사용
public M validateUrlParam(M message, E error, String service, String type, String version, BindingResult result) {
if (result.hasErrors()) {
LOGGER.info("바인딩결과 : {} ", result);
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
try {
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setCode", String.class), error, errorCode);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setMsg", String.class), error,
ValidationErrorMessageAccessor.getMessages().get(errorCode));
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setError", error.getClass()), message, error);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setService", String.class), message, service);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setType", String.class), message, type);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setVersion", String.class), message, version);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
return message;
}
return null;
}
if (result.hasErrors()) {
LOGGER.info("바인딩결과 : {} ", result);
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
try {
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setCode", String.class), error, errorCode);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setMsg", String.class), error,
ValidationErrorMessageAccessor.getMessages().get(errorCode));
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setError", error.getClass()), message, error);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setService", String.class), message, service);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setType", String.class), message, type);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setVersion", String.class), message, version);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
return message;
}
return null;
}
20번 호출에 13,008us 소요됨
# 정리
1. 순수하게 JDK의 리플렉션을 사용한 테스트 수치는 없음
2. Spring ReflectionUtils < 모델 setter 메서드 < Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 순으로 소요시간이 적음
3. 모델 setter 메서드 방식이 가장 빠를 것으로 짐작했으나, 예상과 다른 결과가 나타남. 좀더 테스트가 필요할 것으로 생각됨