주류 속성 복사 도구 속도 비교

21200 단어 자바공구.
요약
본 고 는 네 가지 주류 의 속성 복사 도 구 를 소개 한다.
  • PropertyUtils (commons beanutils)
  • BeanUtils (commons beanutils)
  • BeanUtils (Spring beans)
  • BeanCopier (cglib)

  • 그들의 속성 복사 본 은 모두 자바 내성 을 바탕 으로 복사 대상 유형 은 setter / getter 를 제공 해 야 합 니 다.
    복사 속도 테스트 경과:
  • getter / setter 속도 가 가장 빠 르 지만 수량 이 많은 속성 복사 에는 적용 되 지 않 습 니 다.
  • BeanCopier 속도 가 두 번 째 로 높 고 캐 시 를 사용 하 는 상황 에서 getter / setter 와 차이 가 별로 없다.
  • Spring BeanUtils 는 횟수 가 증가 한 상황 에서 속도 가 비교적 좋 고 횟수 가 적 을 때 comons beanutils 의 두 가지 도구 보다 느리다.
  • Property Utils 는 BeanUtils 보다 속도 가 빠 르 고 안정 적 이다.

  • 1. 속성 복사
    속성 복사
    일상 개발 에 서 는 자바 bean 의 속성 을 다른 자바 bean 으로 복사 하 는 수요 가 많 습 니 다.이 두 bean 은 같은 유형 일 수 있 습 니 다.유형 이 다 를 수도 있 지만 일부 같은 필드 가 있 습 니 다.
    가장 직관 적 인 방법 은 setter / getter 를 사용 하 는 것 입 니 다.
    objA.setName(objB.getName());
    

    이런 방법 은 효율 이 가장 높다.그러나 복사 할 속성 이 많 을 때 setter / getter 는 불편 하고 우아 하지 않 습 니 다.
    수요 가 있 으 면 해당 하 는 해결 방안 이 있 고 다음 과 같은 네 가지 주류 도 구 는 속성 복사 기능 을 제공 합 니 다.
  • org.apache.commons.beanutils.PropertyUtils#copyProperties()
  • org.apache.commons.beanutils.BeanUtils#copyProperties()
  • org.springframework.beans.BeanUtils#copyProperties()
  • net.sf.cglib.beans.BeanCopier

  • 의지 하 다
    org. apache. comons. beanutils. Property Utils. copy Properties 및 org. apache. comons. beanutils. BeanUtils. copy Properties 는 모두 commons-beanutils 에서 제공 합 니 다.
    
        commons-beanutils
        commons-beanutils
        1.9.3
    
    

    org. springframework. beans. BeanUtils. copy Properties 는 spring-beans 에서 제공 합 니 다.
    
        org.springframework
        spring-beans
        5.1.3.RELEASE
    
    

    net. sf. cglib. beans. BeanCopier 는 cglib 에서 제공 합 니 다.
    
        cglib
        cglib
        3.2.7
    
    

    사용 방법
    속성 복사 도구 의 사용 방법 은 모두 비교적 간단 하 다. BeanCopier 을 제외 하고 다른 세 가지 유형 은 모두 정적 인 방법 으로 직접 호출 했다.
    cglib 의 net.sf.cglib.beans.BeanCopier 조금 번 거 롭 습 니 다. 먼저 copier 를 만들어 야 합 니 다.
    BeanCopier beanCopier = net.sf.cglib.beans.BeanCopier.create(SourceBean.class, TargetBean.class, false);
    beanCopier.copy(from, to, null);
    

    네 가지 도구 의 속성 복사 원 리 는 모두 자바 내성 체 제 를 이용 한 것 이다.따라서 복사 가 필요 한 자바 bean 형식 은 getter 와 setter 방법 을 제공 해 야 합 니 다. 복사 가 실 패 했 습 니까?
    동명 이인
    복사 할 때 같은 이름 의 속성 을 만 났 지만 유형 이 다 르 고 몇 가지 도구 의 표현 도 다르다.org.apache.commons.beanutils.PropertyUtils#copyProperties() (동명 setter, 유형 이 다 르 고 이상) org.apache.commons.beanutils.BeanUtils#copyProperties() (동명 setter, 유형 이 다 르 더 라 도 변환 할 수 있 지만 값 이 정확 하지 않 을 수 있 습 니 다) org.springframework.beans.BeanUtils#copyProperties() (동명 setter, 유형 이 다 르 더 라 도 변환 할 수 있 지만 값 이 정확 하지 않 을 수 있 습 니 다) net.sf.cglib.beans.BeanCopier (동명 setter, 유형 이 다 르 더 라 도 변환 할 수 있 지만 값 이 정확 하지 않 을 수 있 습 니 다)
    속도 비교
    코드 테스트 를 통 해 10 회, 1000 회, 1000000 회 각종 수단 의 속 도 는 다음 과 같다.
    10 회 테스트
    처음
    두 번 째
    세 번 째
    평균 값
    매번 평균치
    PropertyUtils.copyProperties
    0
    1
    0
    1/3
    0.033
    BeanUtils.copyProperties
    2
    3
    2
    2.33
    0.233
    SPRING copyProperties
    0
    0
    0
    0
    0
    BeanCopier(without cache)
    0
    0
    0
    0
    0
    BeanCopier
    0
    0
    0
    0
    0
    getter/setter
    0
    0
    0
    0
    0
    1000 회 테스트
    처음
    두 번 째
    세 번 째
    평균 값
    매번 평균치
    PropertyUtils.copyProperties
    22
    21
    16
    19.66
    0.01966
    BeanUtils.copyProperties
    19
    29
    20
    22.66
    0.02266
    SPRING copyProperties
    7
    5
    5
    5.66
    0.00566
    BeanCopier(without cache)
    4
    4
    3
    3.66
    0.00366
    BeanCopier
    0
    0
    1
    0.33
    0.00033
    getter/setter
    0
    0
    0
    0
    0
    1000000 회 테스트
    처음
    두 번 째
    세 번 째
    평균 값
    매번 평균치
    PropertyUtils.copyProperties
    1798
    1770
    1804
    1767.33
    0.00176733
    BeanUtils.copyProperties
    2904
    2937
    2860
    2900.33
    0.00290033
    SPRING copyProperties
    214
    206
    199
    206.33
    0.00020633
    BeanCopier(without cache)
    92
    82
    89
    87.66
    0.00008766
    BeanCopier
    8
    7
    8
    7.66
    0.00000766
    getter/setter
    8
    7
    7
    7.33
    0.00000733
    결론 을 얻 을 수 있다.
  • getter / setter 속도 가 가장 빠 르 지만 수량 이 많은 속성 복사 에는 적용 되 지 않 습 니 다.
  • BeanCopier 속도 가 두 번 째 로 높 고 캐 시 를 사용 하 는 상황 에서 getter / setter 와 차이 가 별로 없다.캐 시 를 사용 하지 않 아 도 속도 가 빠르다.
  • Spring BeanUtils 는 횟수 가 증가 한 상황 에서 속도 가 비교적 좋 고 횟수 가 적 을 때 comons beanutils 의 두 가지 도구 보다 느리다.
  • Property Utils 는 BeanUtils 보다 속도 가 빠 르 고 안정 적 이다.

  • 주의해 야 할 것 은 BeanCopier \ # create 비용 이 비교적 많 기 때문에 빈 Copier 실 체 를 자주 만 들 지 말고 캐 시 를 가장 많이 사용 합 니 다.
    붙다
    테스트 속도 의 코드:
    public class BeanCopyCompareTest {
    
        private static BeanCopier beanCopier = net.sf.cglib.beans.BeanCopier.create(SourceBean.class, TargetBean.class, false);
    
        public static void main(String[] args) throws Exception {
    
            int[] times = {1, 10, 1000, 1000000};
    
            for (int time : times) {
                doCopy(time, (from, to) -> org.apache.commons.beanutils.PropertyUtils.copyProperties(to, from),
                        "org.apache.commons.beanutils.PropertyUtils.copyProperties");
                doCopy(time, (from, to) -> org.apache.commons.beanutils.BeanUtils.copyProperties(to, from),
                        "org.apache.commons.beanutils.BeanUtils.copyProperties");
                doCopy(time, (BeanUtils::copyProperties),
                        "org.springframework.beans.BeanUtils.copyProperties");
                doCopy(time, ((from, to) -> beanCopier.copy(from, to, null)), "net.sf.cglib.beans.BeanCopier");
                doCopy(time, ((from, to) -> {
                    BeanCopier beanCopier = net.sf.cglib.beans.BeanCopier.create(SourceBean.class, TargetBean.class, false);
                    beanCopier.copy(from, to, null);
                }), "net.sf.cglib.beans.BeanCopier(without cache)");
                doCopy(time, ((from, to) -> {
                    to.setAge(from.getAge());
                    to.setGender(from.getGender());
                    to.setName(from.getName());
                    to.setRight(from.getRight());
                }), "getter/setter");
    
                System.out.println("-----------------------------------------------------");
            }
    
        }
    
        static void doCopy(Integer time, BeanCopy beanCopy, String type) throws Exception {
            long startTime = System.currentTimeMillis();
            for (int j = 0; j < time; j++) {
                SourceBean sourceBean = new SourceBean();
                sourceBean.setName("Richard");
                sourceBean.setGender('F');
                sourceBean.setAge(20);
                sourceBean.setRight(true);
    
                TargetBean targetBean = new TargetBean();
                beanCopy.copy(sourceBean, targetBean);
            }
            System.out.printf("  %d   %dms---------%s%n", time, System.currentTimeMillis() - startTime, type);
        }
    
        interface BeanCopy {
            void copy(SourceBean from, TargetBean to) throws Exception;
        }
    }
    

    좋은 웹페이지 즐겨찾기