zl程序教程

您现在的位置是:首页 >  其他

当前栏目

性能测试中的随机数性能问题探索

测试性能 探索 随机数 问题
2023-09-11 14:14:24 时间

在软件测试中,经常会遇到随机数。我简单分成了两类:

  1. 简单取随机数;
  2. 从一个集合中随机取值。

其实第二个场景包含在第一个场景内。对于接口测试来说,通常我们直接使用第二种场景比较多,就是从某一个集合中随机取一个值。如果更复杂一些,每个值拥有不同的权重,其中这个也可以转化成第二个场景来说。

缘起

为什么要把第二个场景和第一个场景分开呢,这个问题源于之前写过的文章ConcurrentHashMap性能测试,当时发现自己封装的com.funtester.frame.SourceCode#random(java.util.List)方法性能存在瓶颈,特别消耗CPU资源。

虽然单机QPS也在50万+,但是因为这个方法很多地方都会用到,所以还是想提升一些性能。所以我就搜索了一些高性能随机数的功能,跟我之前搜到的资料一致,使用java.util.concurrent.ThreadLocalRandom这个实现类是性能最高的,方法如下:

/**
 * 获取随机数,获取1~num 的数字,包含 num
 *
 * @param num 随机数上限
 * @return 随机数
 */
public static int getRandomInt(int num) {
    return ThreadLocalRandom.current().nextInt(num) + 1;
}

针对第二种场景,还有一种实现思路:通过循环去集合中取即可。就是顺序去取,而不是每次都从集合中随机。

在这里插入图片描述
举个例子,我们有10万测试用户进行流量回放,演示代码如下:

def funtest = {
    random(drivers).getGetResponse(random(urls))
}
new FunQpsConcurrent(funtest).start()

这里调用了两次com.funtester.frame.SourceCode#random(java.util.List),当QPS到达10万级别时候,理论上这个方法导致的瓶颈还是有一些影响的。

多线程

所以我用了新思路进行改造,下面是两种思路的对比压测用例,这个测试用例里面其实有三个实现:

  1. random
  2. AtomicInteger
  3. int

用例如下:

package com.funtest.groovytest

import com.funtester.base.constaint.FixedThread
import com.funtester.frame.SourceCode
import com.funtester.frame.execute.Concurrent

import java.util.concurrent.atomic.AtomicInteger

class FunTest extends SourceCode {

    static int times = 1000

    static int thread = 500

    static def integers = 0..100 as List

    static def integer = new AtomicInteger()

    static def i = 0

    static def size = integers.size()

    public static void main(String[] args) {
        RUNUP_TIME = 0
        new Concurrent(new FunTester(), thread, "测试随机数性能").start()
    }

    private static class FunTester extends FixedThread {


        FunTester() {
            super(null, times, true)
        }

        @Override
        protected void doing() throws Exception {
                        10000.times {random(integers)}
//            10000.times {integers.get(integer.getAndIncrement() % size)}
//                        10000.times {integers.get(i++ % size)}
        }

        @Override
        FunTester clone() {
            return new FunTester()
        }
    }

}

由于测试中均达到了CPU硬件瓶颈,相同参数情况下结论比较明显,就没有进行多轮的对比测试。下面分享一下测试结果:

  1. random:1151
  2. AtomicInteger:3152
  3. int:2273

没想到用了java.util.concurrent.atomic.AtomicInteger反而性能更高了,这个问题略微有点深奥,暂时没有思路。

单线程

下面我们来测试一下单线程的性能,下面是我的用例:

package com.funtest.groovytest


import com.funtester.frame.SourceCode

import java.util.concurrent.atomic.AtomicInteger

class FunTestT extends SourceCode {

    static int times = 1000000

    static def integers = 0..100 as List

    static def integer = new AtomicInteger()

    static def i = 0

    static def size = integers.size()

    public static void main(String[] args) {

        time {
            //            times.times {random(integers)}
            //                        times.times {integers.get(integer.getAndIncrement() % size)}
            times.times {integers.get(i++ % size)}
        } , "随机数性能测试"

    }


}

下面是测试结果,这里我记录了执行完所有循环次数的时间,单位是ms(毫秒)。

  1. random:763
  2. AtomicInteger:207
  3. int:270

这下结论明确了,就java.util.concurrent.atomic.AtomicInteger了。

在这里插入图片描述

末了

最终写了一个新的随机对象的方法:

/**
 * 随机选择某个对象
 *
 * @param list
 * @param index 自增索引
 * @param <F>
 * @return
 */
public static <F> F random(List<F> list, AtomicInteger index) {
    if (list == null || list.isEmpty()) ParamException.fail("数组不能为空!");
    return list.get(index.getAndIncrement() % list.size());
}

软件测试工程师自学教程:

这才是2022最精细的自动化测试自学教程,我把它刷了无数遍才上岸字节跳动,做到涨薪20K【值得自学软件测试的人刷】

接口性能测试 — 软件测试人必会618实战场景分析

软件测试工程师月薪2W以上薪资必学技能 — Python接口自动化框架封装.

美团面试真题_高级测试25K岗位面试 — 软件测试人都应该看看

测试开发之全面剖析自动化测试平台 — 软件测试人的必经之路

软件测试必会_Jmeter大厂实战 — 仅6步可实现接口自动化测试

Jmeter实战讲解案例 — 软件测试人必会

最后: 可以在公众号:伤心的辣条 ! 自行领取一份216页软件测试工程师面试宝典文档资料【免费的】。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

我推荐一个【Python自动化测试交流群:746506216】,大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,助你快速进阶Python自动化测试/测试开发,走向高薪之路。

喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一 键三连哦!