使用Bean其实优于Map

在很长的时间里,一直以为使用反射技术效率低,对比于使用反射创建对象,可能直接创建Map更快,但是这种认知是不准确的,

 

创建对象耗时:class.newInstance  > new HashMap > new Object

填充值耗时   :map.put > obj.setValue > field.set

 

理论下Java反射并不一定最慢,但是因为Field对象通常以数组存储,使用过程涉及大量的数组遍历,导致效率明显降低,

针对特殊的业务,可以预先处理一部分的反射,可以达到与Map相当的效率(取决于Field参数个数)

 

以下以创建一百万个对象为例:

package spring;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.client.bean.Person;

public class Test {
    public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        {
            //在很长的时间里,一直以为map是快速的存储结构,实际测试下,反而是最慢的
            //(但是map支持无限制地填充数据,这一点优于bean对象)
            //慢的原因,主要是在创建HashMap这一步,这一步占了超过一半的耗时
            List<Map<String,Object>> l = new ArrayList<>();
            Map<String,Object> map;
            int cnt = 1000000;
            long start = System.nanoTime();
            while(cnt-->0){
                map= new HashMap<>();
                map.put("name", "xiaoming");
                map.put("age", cnt);
                map.put("name", "xiaoming");
                map.put("age", cnt);
                l.add(map);
            }
            long end = System.nanoTime();
            System.out.println(l.size());
            System.out.println(start);
            System.out.println(end);
            System.out.println(end-start);
        }
        {
            //阿里的JSON本质是Map,效率上稍微低于map
            List<JSONObject> l = new ArrayList<>();
            JSONObject map;
            int cnt = 1000000;
            long start = System.nanoTime();
            while(cnt-->0){
                map= new JSONObject();
                map.put("name", "xiaoming");
                map.put("age", cnt);
                l.add(map);
            }
            long end = System.nanoTime();
            System.out.println(l.size());
            System.out.println(start);
            System.out.println(end);
            System.out.println(end-start);
        }
        {
            //使用bean对象
            List<Person> l = new ArrayList<>();
            Person map;
            int cnt = 1000000;
            long start = System.nanoTime();
            while(cnt-->0){
                map= new Person();
                map.setName("xiaoming");
                map.setAge(cnt);
                l.add(map);
            }
            long end = System.nanoTime();
            System.out.println(l.size());
            System.out.println(start);
            System.out.println(end);
            System.out.println(end-start);  
        }
        {   
            //对java反射进行优化,先解析一部分参数,如果用以下这种编码方式,它的效率是最快的
            //但是做map.get的时候,随着参数的增多,达到某个阶段,耗时会超过Bean的set函数
       //其中while循环下new Person()这一步,实际生产中,应该是class.newInstance(),这是极耗时的一步,导致了最终的执行效率并不高
List<Person> l = new ArrayList<>(); Person map; int cnt = 1000000; Field fn = Person.class.getDeclaredField("name"); fn.setAccessible(true); Field fa = Person.class.getDeclaredField("age"); fa.setAccessible(true); Map<String,Field> f = new HashMap<>(); f.put("name", fn); f.put("age", fa); long start = System.nanoTime(); while(cnt-->0){ map= new Person(); f.get("name").set(map, "xiaoming"); f.get("age").set(map, cnt); l.add(map); } long end = System.nanoTime(); System.out.println(l.size()); System.out.println(start); System.out.println(end); System.out.println(end-start); } { //所有的反射留到使用时再解析,这种方式会随着参数变多, //耗时也越来越多,超过某个阶段,效率低于Map List<Person> l = new ArrayList<>(); Person map; int cnt = 1000000; long start = System.nanoTime(); Field fa,fn; while(cnt-->0){ fn = Person.class.getDeclaredField("name"); fn.setAccessible(true); fa = Person.class.getDeclaredField("age"); fa.setAccessible(true); map= new Person(); fn.set(map, "xiaoming"); fa.set(map, cnt); l.add(map); } long end = System.nanoTime(); System.out.println(l.size()); System.out.println(start); System.out.println(end); System.out.println(end-start); } } }

 

转载于:https://www.cnblogs.com/chenss15060100790/p/10237751.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值