The introduction

Two dogs: two fat quick wake up, hurriedly see just alarm email, you last time write save user interface time (” two fat parameters check bumpy road “) greatly rise, hurriedly check the reasons. Two fat: good, see immediately, inner heart drama can be dye-in-the air (in the heart but complain, big midday stir me to get rich dream, just dream of the stock that I buy again rose stop to be awakened). After all, it is my own bug, and I will fix it with tears in my eyes. Two fat to the analysis of this problem or handy, after all, has been a seasoned professional.

Test environment recurring problems

Two fat first through the internal monitoring tools to see whether the network is normal during this period of time, and CPU usage, database time, etc., these indicators seem to be normal, the only slight difference is that this period of traffic rose some, it is certain that the company is spending money on marketing advertising. Then two fat and cat (public comment open source monitoring tool) analysis of several requests, each stage of the time to see down ok. If only the production environment problems could be replicated in the test environment, it would be much easier to solve the problem. Isn’t production flow up a bit? That test environment to pressure test a, two fat decisive download a JMeter (pressure test tool) in the test environment to carry out a crazy pressure test, as expected, and the production of the same problem. If you can reproduce the problem, you’re a big step closer to solving it.

Arthas is faulty

The problem is repeated, and the next step is to figure out where the interface is time-consuming. Generally, we print the time spent in each step by recording logs for places that take a long time to find an interface. This is common practice, but the last time the department technology master “Two Dogs” shared an artifact arthas could output the time on each node on the method path. I have never had a chance to use it for practical operation, but today I can finally practice with it. Installation of what is not introduced, the official website are written in more detail, and the documents are also in Chinese, very easy to use. Let’s use Arthas. The page is successfully started

arthas
trace

org.apache.commons.beanutils.BeanUtils#copyProperties
apache
low

Performance comparison of common attribute assignment operations using the JMH

  • useget,setMethod replication.
  • cglibtheBeanCopier.
  • SpringtheBeanUtils
  • apachetheBeanUtils
  • MapStructLet’s do a performance comparison of the above operations. Write the following test class.
/ * * *@author:
 * @Date: 2020/7/11
 * @Description: * /
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 5, time = 5)
@Threads(6)
@Fork(1)
@State(value = Scope.Benchmark)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class BeanCopyTest {
    @Param(value = {"1"."10"."100"})
    private int count;

    public UserBO bo;

    public  BeanCopier copier;

    @Setup(Level.Trial) // Initialize the method before all Benchmark runs
    public void init(a) {
        copier = BeanCopier.create(UserBO.class, UserVO.class, false);
        bo = new UserBO();
        bo.setUserName("Java financial");
        bo.setAge(1);
        bo.setIdCard("88888888");
        bo.setEmail("Java financial @ qq.com");
    }


    public static void main(String[] args) throws RunnerException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
       Options opt = new OptionsBuilder().include(BeanCopyTest.class.getSimpleName()).result("result.json").resultFormat(ResultFormatType.JSON).build();
        new Runner(opt).run();

    }

    /**
     * 使用mapStruct来操作
     */
    @Benchmark
    public void mapStruct(a) {
        for (int i = 1; i <= count; i++) { UserVO vo = UserMapping.INSTANCE.converter(bo); }}/** * Manually set and Get */
    @Benchmark
    public void setAndGet(a) {
        for (int i = 1; i <= count; i++) {
            UserVO userVO = newUserVO(); userVO.setUserName(bo.getUserName()); userVO.setEmail(bo.getEmail()); userVO.setSex(bo.getSex()); userVO.setIdCard(bo.getIdCard()); userVO.setAge(bo.getAge()); }}/** * Use cglib's copy method */
    @Benchmark
    public void cglibBeanCopier(a) {
        for (int i = 1; i <= count; i++) {
            UserVO vo = new UserVO();
            copier.copy(bo, vo, null); }}/** * Use the copyProperties method provided by Spring
    @Benchmark
    public void springBeanUtils(a) {
        for (int i = 1; i <= count; i++) {
            UserVO vo = newUserVO(); BeanUtils.copyProperties(bo, vo); }}/** * use apache's copyProperties method *@throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @Benchmark
    public void apacheBeanUtils(a) throws InvocationTargetException, IllegalAccessException {
        for (int i = 1; i <= count; i++) {
            UserVO vo = newUserVO(); org.apache.commons.beanutils.BeanUtils.copyProperties(vo, bo); }}Copy the code

The final test results are as follows:

Benchmark                     (count)  Mode  Cnt          Score          Error  Units
BeanCopyTest.apacheBeanUtils        1  avgt    5    2462103.419 ±  2292830.495  ns/op
BeanCopyTest.apacheBeanUtils       10  avgt    5   21025926.689 ± 11254755.603  ns/op
BeanCopyTest.apacheBeanUtils      100  avgt    5  193235312.113 ± 37929707.246  ns/op
BeanCopyTest.cglibBeanCopier        1  avgt    5          4.936 ±        1.187  ns/op
BeanCopyTest.cglibBeanCopier       10  avgt    5          4.820 ±        1.963  ns/op
BeanCopyTest.cglibBeanCopier      100  avgt    5          4.269 ±        0.890  ns/op
BeanCopyTest.mapStruct              1  avgt    5          4.809 ±        1.720  ns/op
BeanCopyTest.mapStruct             10  avgt    5          4.947 ±        1.320  ns/op
BeanCopyTest.mapStruct            100  avgt    5          4.440 ±        1.191  ns/op
BeanCopyTest.setAndGet              1  avgt    5          3.780 ±        1.785  ns/op
BeanCopyTest.setAndGet             10  avgt    5          3.930 ±        1.788  ns/op
BeanCopyTest.setAndGet            100  avgt    5          4.069 ±        2.181  ns/op
BeanCopyTest.springBeanUtils        1  avgt    5       1190.563 ±      165.574  ns/op
BeanCopyTest.springBeanUtils       10  avgt    5      10887.244 ±     1228.026  ns/op
BeanCopyTest.springBeanUtils      100  avgt    5     109686.562 ±     7485.261  ns/op
Copy the code

  • From the above conclusion we can find that the best performance is rankingget,setMethod replication, followed bymapStructandThe additional BeanCopier, and thenSpring's beanUtilsAnd finallyThe apache BeanUtils.
  • If you are interested in the above test performance, the code has been uploadedgithubYou can download and run the results.The code address
  • aboutJMHThe use of is not introduced, interested in Google. But if you want to do a performance comparison, which is really recommended, you can export the resultsjsonThe file then generates the chart.

Why does apacheBeanUtils have the worst performance

Both apacheBeanUtils and Spring’s beanUtils are assigned using reflection, so why is apacheBeanUtils performing worse? There are no secrets under the source code, so let’s take a look at the source code for this method.

Apache BeanUtils

  • Spring’s beanUtil directly uses reflection province, clean, the core code is shown in the following figure.

  • In fact, in ** “Alibaba Development Manual” ** (can be obtained in the public number [Java Finance] reply “Taishan”) there is also a description of the attribute of copy to avoid using apcheBeanUtils

  • If you want to replace Spring BeanUtils with Apache BeanUtils in your production environment, you need to be careful that both of these methods are copyProperties but their arguments are reversed, so don’t just change the package name that you introduced.

conclusion

  • Words in actual use are generally not usedgetandsetMethod copying, easy to miss properties and also a physical task. It is recommended to usemapStruct, during compilation,MapStructAn implementation of this interface is generated, and it can also implement mappings of different names, such as thenameMap tousername, the flexibility is high.
  • Two fat feeling today harvest full ah, a learnedjmeter,arthas,JMHThe use of three software.

The end of the

  • Due to their lack of knowledge, it is hard to avoid mistakes, if you find the wrong place, also hope to leave a message to me to point out, I will correct it.
  • If you think the article is good, your retweet, share, praise, like, comment is the biggest encouragement to me.
  • Thank you for reading. I very much welcome and thank you for your attention.