最近的这个项目一直使用protocol buffer作为协议层,大家在使用的过程中发现,每次在创建消息的builder——即newBuilder的时候,会非常的慢(常常需要20ms以上),以至于大家现在基本是谈newBuilder色变的地步。今天亮亮终于忍不住,问我为啥一个builder的创建那么慢呢,我正在玩儿游戏,抽空调出源码来看了一下,发现里面就真是new了一个Builder对象,这个Builder对象也没有那么的复杂,而且构造方法也足够简单,没有逻辑,是啊,我突然回答不了亮亮的问题了。只能说:你等等,我玩儿完游戏研究一下。
仔细思考一下,如果一个类的构造方法里没有什么逻辑,那么就看看它的实例字段、超类字段以及构造方法,挨个查了一遍,发现一个Builder的继承结构是这样的:
看着有些吓人,但是说实话,每一个类中的字段以及构造方法都不会让它的创建超过20ms,那到底问题在哪里?
如果创建不快的话,那么一定是费在了第一次类加载上。为了验证这个推测,我将newBuilder的调用放到了一个循环中,查看每次循环的时间,结果和推测的一样,除了第一次吓人之外,之后基本在毫秒级别都是0。
有了这个验证,那么我们继续证明,将该Builder的加载放到整个测试之外,用Class.forName的方式加载之后再测试,这下就更加明了了,第一次的newBuilder只用了5ms左右,其它的都是0ms级别的。
仔细看了Builder和它的各种父类的定义,全部都是static class,也就是说,在我们真正使用到它之前,JVM确实不会加载它,这也就是为什么它的第一次会非常慢的原因了。
时间: 2024-12-29 19:49:31