复制对象耗时比较(PO2Response)


前言

在开发过程中,经常会遇到将对象转为response返回出去,或着将request转PO,又或者将PO转为VO的场景。
下面就对比下:hutool,fastjson,jackson,jdk的效率

一、准备工作

1、导入依赖

jdk版本1.8

		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.79</version>
            <scope>compile</scope>
        </dependency>
        
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.6</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

2、PO对象

@Data
public class ParentPO {
    private String name;

    private List<ChildPO> childList;

    private WifePO wife;

    public ParentPO() {
    }

    public ParentPO(String name, List<ChildPO> childList, WifePO wife) {
        this.name = name;
        this.childList = childList;
        this.wife = wife;
    }
}
@Data
public class ChildPO {
    private String name;

    public ChildPO(String name) {
        this.name = name;
    }
}
@Data
public class WifePO {
    private String name;

    public WifePO(String name) {
        this.name = name;
    }
}

3、 response对象

@Data
public class ParentResponse implements Serializable {
    private String name;

    private List<ChildResponse> childList;

    private WifeResponse wife;

    public ParentResponse() {
    }
}

@Data
public class ChildResponse implements Serializable {
    private String name;

    public ChildResponse() {
    }

    public ChildResponse(String name) {
        this.name = name;
    }
}

@Data
public class WifeResponse implements Serializable {
    private String name;

    public WifeResponse() {
    }

    public WifeResponse(String name) {
        this.name = name;
    }
}

二、比较代码

package com.example.demo.demo2;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.python.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;


public class Demo2Controller {
    public static Integer CHILD_NUM = 2;

    public static ParentPO getParent() {
        List<ChildPO> childPOList = getChildList();
        return new ParentPO("张", childPOList, new WifePO("李"));
//                return new ParentPO("张", Lists.newArrayList(new ChildPO("1"),new ChildPO("2"),new ChildPO("3"),new ChildPO("4")), new WifePO("李"));

    }

    private static List<ChildPO> getChildList() {
        List<ChildPO> childPOList = new ArrayList<>();
        while (CHILD_NUM > 0) {
            childPOList.add(new ChildPO("" + CHILD_NUM--));
        }
        return childPOList;
    }

    public static void main(String[] args) throws Exception {
        Long start1 = System.currentTimeMillis();
        ParentPO p1 = getParent();
        Long end1 = System.currentTimeMillis();
        System.out.println("创建parent耗时 = " + (end1 - start1));
        System.out.println("创建parent =               " + JSONObject.toJSONString(p1));

        Long start2 = System.currentTimeMillis();
        ParentResponse p2 = BeanUtil.toBean(p1, ParentResponse.class);
        Long end2 = System.currentTimeMillis();
        System.out.println("hutool赋值到Parent2耗时 = " + (end2 - start2));
        System.out.println("hutool赋值到Parent2 =      " + JSONObject.toJSONString(p2));

        Long start3 = System.currentTimeMillis();
        ParentResponse p3 = JSONObject.parseObject(JSONObject.toJSONString(p1), ParentResponse.class);
        Long end3 = System.currentTimeMillis();
        System.out.println("fastjson赋值到Parent2耗时 = " + (end3 - start3));
        System.out.println("fastjson赋值到Parent2 =    " + JSONObject.toJSONString(p3));

        Long start4 = System.currentTimeMillis();
        ObjectMapper mapper = new ObjectMapper();
        ParentResponse p4 = mapper.readValue(mapper.writeValueAsString(p2), ParentResponse.class);
        Long end4 = System.currentTimeMillis();
        System.out.println("jackson赋值到Parent2耗时 = " + (end4 - start4));
        System.out.println("jackson赋值到Parent2 =     " + JSONObject.toJSONString(p4));

        Long start5 = System.currentTimeMillis();
        ParentResponse p5 = BeanUtil.toBean(p1, ParentResponse.class);
        BeanUtils.copyProperties(p1, p5);
        Long end5 = System.currentTimeMillis();
        System.out.println("jdk赋值到Parent2耗时 = " + (end5 - start5));
        System.out.println("jdk赋值到Parent2 =         " + JSONObject.toJSONString(p5));
    }
}

用CHILD_NUM控制parent对象的大小(parent有N个child)

当CHILD_NUM = 5时,执行结果如下:

创建parent耗时 = 2
hutool赋值到Parent2耗时 = 139
fastjson赋值到Parent2耗时 = 127
jackson赋值到Parent2耗时 = 235
jdk赋值到Parent2耗时 = 105

当CHILD_NUM = 50时,执行结果如下:

创建parent耗时 = 1
hutool赋值到Parent2耗时 = 171
fastjson赋值到Parent2耗时 = 125
jackson赋值到Parent2耗时 = 238
jdk赋值到Parent2耗时 = 141

当CHILD_NUM = 500时,执行结果如下:

创建parent耗时 = 3
hutool赋值到Parent2耗时 = 274
fastjson赋值到Parent2耗时 = 117
jackson赋值到Parent2耗时 = 222
jdk赋值到Parent2耗时 = 178

当CHILD_NUM =5000时,执行结果如下:

创建parent耗时 = 8
hutool赋值到Parent2耗时 = 738
fastjson赋值到Parent2耗时 = 158
jackson赋值到Parent2耗时 = 269
jdk赋值到Parent2耗时 = 547

当CHILD_NUM = 50000时,执行结果如下:

创建parent耗时 = 30
hutool赋值到Parent2耗时 = 4785
fastjson赋值到Parent2耗时 = 187
jackson赋值到Parent2耗时 = 285
jdk赋值到Parent2耗时 = 3997

总结

从结果上来看,综合选择fastjson,效率是比较高的。

hutool速度为啥那么慢呢,从方法上看,是因为使用了反射(反射技术速度慢)

public static <T> T toBean(Object source, Class<T> clazz, CopyOptions options) {
        return toBean(source, () -> {
            return ReflectUtil.newInstanceIfPossible(clazz);
        }, options);
    }

jdk也是内部使用了反射,所以速度慢
这个方法内使用反射实现copy

org.springframework.beans.BeanUtils#copyProperties(java.lang.Object, java.lang.Object, java.lang.Class<?>, java.lang.String...)

fastjson快的原因:继承JSON,本质上是转为Map

jackson不知道(代码没看懂)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值